From bd31104b66bdda8da51d44e2b9b011d2b24076ee Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Mon, 23 Mar 2026 11:18:44 +0100 Subject: [PATCH 01/22] Refl1d fix (#302) * assure refl1d actually runs from the GUI * don't fail on codecov upload --- .github/workflows/python-ci.yml | 2 +- .../tutorials/fitting/simple_fitting.ipynb | 117 +++++++++++++++++- src/easyreflectometry/project.py | 10 ++ tests/test_project.py | 14 +++ 4 files changed, 136 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 90967cd9..1d33313f 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -61,7 +61,7 @@ jobs: name: unit-tests-job flags: unittests files: ./coverage-unit.xml - fail_ci_if_error: true + fail_ci_if_error: false verbose: true token: ${{ secrets.CODECOV_TOKEN }} slug: EasyScience/EasyReflectometryLib diff --git a/docs/src/tutorials/fitting/simple_fitting.ipynb b/docs/src/tutorials/fitting/simple_fitting.ipynb index 5dcd5eb8..ea761e75 100644 --- a/docs/src/tutorials/fitting/simple_fitting.ipynb +++ b/docs/src/tutorials/fitting/simple_fitting.ipynb @@ -30,7 +30,9 @@ "source": [ "%matplotlib inline\n", "\n", + "import matplotlib.pyplot as plt\n", "import pooch\n", + "import refl1d\n", "import refnx\n", "\n", "import easyreflectometry\n", @@ -63,7 +65,8 @@ "outputs": [], "source": [ "print(f'easyreflectometry: {easyreflectometry.__version__}')\n", - "print(f'refnx: {refnx.__version__}')" + "print(f'refnx: {refnx.__version__}')\n", + "print(f'refl1d: {refl1d.__version__}')" ] }, { @@ -395,7 +398,7 @@ "## Choosing our calculation engine\n", "\n", "The `easyreflectometry` package enables the calculation of the reflectometry profile using either [*refnx*](https://refnx.readthedocs.io/) or [*Refl1D*](https://refl1d.readthedocs.io/en/latest/).\n", - "For this tutorial, we will stick to the current default, which is *refnx*. \n", + "We will first run the fit with the current default, *refnx*, and then rebuild the same starting model with *Refl1D* to compare the results.\n", "The calculator must be created and associated with the model that we are to fit. " ] }, @@ -464,7 +467,8 @@ "metadata": {}, "outputs": [], "source": [ - "analysed = fitter.fit(data)" + "analysed_refnx = fitter.fit(data)\n", + "analysed = analysed_refnx" ] }, { @@ -513,18 +517,119 @@ "model" ] }, + { + "cell_type": "markdown", + "id": "2b2fe558", + "metadata": {}, + "source": [ + "## Repeating the optimisation with Refl1D\n", + "\n", + "To compare backends fairly, we rebuild the same initial model and then switch the calculator to `refl1d`.\n", + "This ensures that the second optimisation starts from the same parameter guesses rather than from the already-optimised `refnx` result." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "341abc6f", + "metadata": {}, + "outputs": [], + "source": [ + "print(f'refl1d: {refl1d.__version__}')\n", + "\n", + "si_refl1d = Material(sld=2.07, isld=0, name='Si')\n", + "sio2_refl1d = Material(sld=3.47, isld=0, name='SiO2')\n", + "film_refl1d = Material(sld=2.0, isld=0, name='Film')\n", + "d2o_refl1d = Material(sld=6.36, isld=0, name='D2O')\n", + "\n", + "si_layer_refl1d = Layer(material=si_refl1d, thickness=0, roughness=0, name='Si layer')\n", + "sio2_layer_refl1d = Layer(material=sio2_refl1d, thickness=30, roughness=3, name='SiO2 layer')\n", + "film_layer_refl1d = Layer(material=film_refl1d, thickness=250, roughness=3, name='Film Layer')\n", + "subphase_refl1d = Layer(material=d2o_refl1d, thickness=0, roughness=3, name='D2O Subphase')\n", + "\n", + "superphase_refl1d = Multilayer([si_layer_refl1d, sio2_layer_refl1d], name='Si/SiO2 Superphase')\n", + "sample_refl1d = Sample(superphase_refl1d, Multilayer(film_layer_refl1d), Multilayer(subphase_refl1d), name='Film Structure')\n", + "\n", + "resolution_function_refl1d = PercentageFwhm(0.02)\n", + "model_refl1d = Model(\n", + " sample=sample_refl1d,\n", + " scale=1,\n", + " background=1e-6,\n", + " resolution_function=resolution_function_refl1d,\n", + " name='Film Model (Refl1D)'\n", + ")\n", + "\n", + "sio2_layer_refl1d.thickness.bounds = (15, 50)\n", + "film_layer_refl1d.thickness.bounds = (200, 300)\n", + "sio2_layer_refl1d.roughness.bounds = (1, 15)\n", + "film_layer_refl1d.roughness.bounds = (1, 15)\n", + "subphase_refl1d.roughness.bounds = (1, 15)\n", + "film_layer_refl1d.material.sld.bounds = (0.1, 3)\n", + "model_refl1d.background.bounds = (1e-8, 1e-5)\n", + "model_refl1d.scale.bounds = (0.5, 1.5)\n", + "\n", + "interface_refl1d = CalculatorFactory()\n", + "interface_refl1d.switch('refl1d')\n", + "model_refl1d.interface = interface_refl1d\n", + "\n", + "print(interface_refl1d.current_interface.name)" + ] + }, + { + "cell_type": "markdown", + "id": "2f764d79", + "metadata": {}, + "source": [ + "We can now fit the same dataset with `refl1d` and compare the fitted curve and reduced chi-squared with the earlier `refnx` result." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70229cf9", + "metadata": {}, + "outputs": [], + "source": [ + "fitter_refl1d = MultiFitter(model_refl1d)\n", + "analysed_refl1d = fitter_refl1d.fit(data)\n", + "\n", + "print(f'refnx reduced chi: {analysed_refnx[\"reduced_chi\"]:.4f}')\n", + "print(f'refl1d reduced chi: {analysed_refl1d[\"reduced_chi\"]:.4f}')\n", + "\n", + "qz = data['coords']['Qz_0'].values\n", + "reflectivity = data['data']['R_0'].values\n", + "uncertainty = data['data']['R_0'].variances**0.5\n", + "\n", + "plt.figure(figsize=(8, 5))\n", + "plt.errorbar(qz, reflectivity, yerr=uncertainty, fmt='o', markersize=3, color='black', alpha=0.6, label='Data')\n", + "plt.plot(qz, analysed_refnx['R_0_model'].values, linewidth=2.5, label='refnx fit')\n", + "plt.plot(qz, analysed_refl1d['R_0_model'].values, linewidth=2.5, label='refl1d fit')\n", + "plt.yscale('log')\n", + "plt.xlabel(r'$Q_z$ (1/Å)')\n", + "plt.ylabel('Reflectivity')\n", + "plt.grid(True, which='both', alpha=0.25)\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "print('refnx model')\n", + "print(model)\n", + "print()\n", + "print('refl1d model')\n", + "print(model_refl1d)" + ] + }, { "cell_type": "markdown", "id": "df6db8c3-6515-478b-bd2e-aac967579231", "metadata": {}, "source": [ - "We note here that the results obtained are very similar to those from the [*refnx* tutorial](https://refnx.readthedocs.io/en/latest/getting_started.html#Fitting-a-neutron-reflectometry-dataset), which is hardly surprising given that we have used the *refnx* engine in this example." + "We note here that the results obtained with [*refnx*](https://refnx.readthedocs.io/en/latest/) and [*Refl1D*](https://refl1d.readthedocs.io/en/latest/) are very similar for this simple slab model, with only small backend-dependent differences in the fitted curve and optimised parameters." ] } ], "metadata": { "kernelspec": { - "display_name": "easyref", + "display_name": ".venv (3.11.9)", "language": "python", "name": "python3" }, @@ -538,7 +643,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.9" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 6f7096c1..67febcc0 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -220,7 +220,17 @@ def calculator(self) -> str: @calculator.setter def calculator(self, calculator: str) -> None: + if calculator == self._calculator.current_interface_name: + return + self._calculator.switch(calculator) + self._calculator.reset_storage() + + for model in self._models: + model.generate_bindings() + + self._fitter = None + self._fitter_model_index = None @property def minimizer(self) -> AvailableMinimizers: diff --git a/tests/test_project.py b/tests/test_project.py index b93df068..3876e4b8 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -268,6 +268,20 @@ def test_fitter_new_model_index(self): # Expect assert fitter_0 is not fitter_1 + def test_switch_calculator_rebuilds_model_bindings(self): + # When + project = Project() + project.default_model() + + # Then + project.calculator = 'refl1d' + reflectivity = project.model_data_for_model_at_index(0, np.array([0.01, 0.05, 0.1, 0.5])) + + # Expect + assert project.calculator == 'refl1d' + assert len(reflectivity.y) == 4 + assert np.all(np.isfinite(reflectivity.y)) + def test_experiments(self): # When project = Project() From de04b4970464e177c8dc21b3fe13d664174e4eb5 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Mon, 13 Apr 2026 11:26:25 +0200 Subject: [PATCH 02/22] Improved limits for certain parameters (#304) * initial implementation * set `disable` status on relevant sub/super-phase parameters * fixed tests * fixes after CR * fixed tests --- src/easyreflectometry/limits.py | 44 +++++ src/easyreflectometry/model/model.py | 2 + src/easyreflectometry/project.py | 49 ++++++ .../sample/elements/layers/layer.py | 5 + .../sample/elements/materials/material.py | 4 + tests/model/test_model.py | 4 +- .../elements/materials/test_material.py | 25 ++- tests/test_limits.py | 150 ++++++++++++++++++ tests/test_project.py | 29 ++++ 9 files changed, 297 insertions(+), 15 deletions(-) create mode 100644 src/easyreflectometry/limits.py create mode 100644 tests/test_limits.py diff --git a/src/easyreflectometry/limits.py b/src/easyreflectometry/limits.py new file mode 100644 index 00000000..691f86e3 --- /dev/null +++ b/src/easyreflectometry/limits.py @@ -0,0 +1,44 @@ +import numpy as np +from easyscience.variable import Parameter + +# Fixed-range limit definitions +SLD_LIMITS = (-1.0, 10.0) +SCALE_LIMITS = (0.0, 10.0) + + +def apply_default_limits(parameter: Parameter, kind: str) -> None: + """Apply default min/max to a parameter if current bounds are infinite. + + :param parameter: The parameter to adjust. + :type parameter: Parameter + :param kind: One of 'thickness', 'roughness', 'sld', 'isld', 'scale'. + :type kind: str + """ + if not parameter.independent: + return + + if kind in ('thickness', 'roughness'): + _apply_percentage_limits(parameter) + elif kind in ('sld', 'isld'): + _apply_fixed_limits(parameter, *SLD_LIMITS) + elif kind == 'scale': + _apply_fixed_limits(parameter, *SCALE_LIMITS) + + +def _apply_percentage_limits(parameter: Parameter) -> None: + """Set min to 50% and max to 200% of the current value, only if current bounds are inf.""" + value = parameter.value + if value == 0.0: + return + if np.isinf(parameter.min): + parameter.min = 0.5 * value + if np.isinf(parameter.max): + parameter.max = 2.0 * value + + +def _apply_fixed_limits(parameter: Parameter, low: float, high: float) -> None: + """Set fixed min/max, only if current bounds are inf.""" + if np.isinf(parameter.min) and low <= parameter.value: + parameter.min = low + if np.isinf(parameter.max) and high >= parameter.value: + parameter.max = high diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index e4bdaac5..7f651fa2 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -12,6 +12,7 @@ from easyscience import global_object from easyscience.variable import Parameter +from easyreflectometry.limits import apply_default_limits from easyreflectometry.sample import BaseAssembly from easyreflectometry.sample import Sample from easyreflectometry.utils import get_as_parameter @@ -86,6 +87,7 @@ def __init__( resolution_function = PercentageFwhm(DEFAULTS['resolution']['value']) scale = get_as_parameter('scale', scale, DEFAULTS) + apply_default_limits(scale, 'scale') background = get_as_parameter('background', background, DEFAULTS) self.color = color self._is_default = False diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 67febcc0..7e1ab3c9 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -21,6 +21,7 @@ from easyreflectometry.data.measurement import extract_orso_title from easyreflectometry.data.measurement import load_data_from_orso_file from easyreflectometry.fitting import MultiFitter +from easyreflectometry.limits import apply_default_limits from easyreflectometry.model import Model from easyreflectometry.model import ModelCollection from easyreflectometry.model import PercentageFwhm @@ -91,6 +92,52 @@ def parameters(self) -> List[Parameter]: parameters.append(param) return parameters + def _sync_parameter_states(self) -> None: + """Apply project-level parameter enablement and default limits. + + Superphase thickness/roughness and subphase thickness are physically + meaningless and are marked as disabled. Thickness and roughness default + ranges are then applied only to enabled parameters created from project + defaults, leaving explicit user-provided bounds untouched. + """ + if self._models is None: + return + + disabled_ids: set[int] = set() + for model in self._models: + sample = model.sample + if sample is None or len(sample) == 0: + continue + superphase = sample.superphase + if superphase is not None: + disabled_ids.add(id(superphase.thickness)) + disabled_ids.add(id(superphase.roughness)) + subphase = sample.subphase + if subphase is not None: + disabled_ids.add(id(subphase.thickness)) + + for model in self._models: + sample = model.sample + if sample is None or len(sample) == 0: + continue + for assembly in sample: + for layer in assembly.layers: + self._sync_layer_parameter_state(layer.thickness, 'thickness', disabled_ids) + self._sync_layer_parameter_state(layer.roughness, 'roughness', disabled_ids) + + def _sync_layer_parameter_state(self, parameter: Parameter, kind: str, disabled_ids: set[int]) -> None: + """Update a layer parameter's enabled state and pending default limits.""" + if id(parameter) in disabled_ids: + parameter.enabled = False + return + + if getattr(parameter, 'default_limits_pending', False): + delattr(parameter, 'default_limits_pending') + if getattr(parameter, 'enabled', True): + parameter.min = -np.inf + parameter.max = np.inf + apply_default_limits(parameter, kind) + @property def q_min(self): if self._q_min is None: @@ -204,6 +251,7 @@ def models(self, models: ModelCollection) -> None: self._materials.extend(self._get_materials_in_models()) for model in self._models: model.interface = self._calculator + self._sync_parameter_states() @property def fitter(self) -> MultiFitter: @@ -334,6 +382,7 @@ def add_sample_from_orso(self, sample: Sample) -> None: model.interface = self._calculator # Extract materials from the new model and add to project materials self._materials.extend(self._get_materials_from_model(model)) + self._sync_parameter_states() # Switch to the newly added model so its data is visible in the UI self.current_model_index = len(self._models) - 1 diff --git a/src/easyreflectometry/sample/elements/layers/layer.py b/src/easyreflectometry/sample/elements/layers/layer.py index 28f13a38..513b18f9 100644 --- a/src/easyreflectometry/sample/elements/layers/layer.py +++ b/src/easyreflectometry/sample/elements/layers/layer.py @@ -65,18 +65,23 @@ def __init__( if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) + thickness_value = thickness thickness = get_as_parameter( name='thickness', value=thickness, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Thickness', ) + thickness.default_limits_pending = not isinstance(thickness_value, Parameter) + + roughness_value = roughness roughness = get_as_parameter( name='roughness', value=roughness, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Roughness', ) + roughness.default_limits_pending = not isinstance(roughness_value, Parameter) super().__init__( name=name, diff --git a/src/easyreflectometry/sample/elements/materials/material.py b/src/easyreflectometry/sample/elements/materials/material.py index 249cd160..8c030031 100644 --- a/src/easyreflectometry/sample/elements/materials/material.py +++ b/src/easyreflectometry/sample/elements/materials/material.py @@ -7,6 +7,7 @@ from easyscience import global_object from easyscience.variable import Parameter +from easyreflectometry.limits import apply_default_limits from easyreflectometry.utils import get_as_parameter from ...base_core import BaseCore @@ -62,12 +63,15 @@ def __init__( default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Sld', ) + apply_default_limits(sld, 'sld') + isld = get_as_parameter( name='isld', value=isld, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Isld', ) + apply_default_limits(isld, 'isld') super().__init__( name=name, diff --git a/tests/model/test_model.py b/tests/model/test_model.py index 5745501e..49ce60fc 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -37,7 +37,7 @@ def test_default(self): assert_equal(str(p.scale.unit), 'dimensionless') assert_equal(p.scale.value, 1.0) assert_equal(p.scale.min, 0.0) - assert_equal(p.scale.max, np.inf) + assert_equal(p.scale.max, 10.0) assert_equal(p.scale.fixed, True) assert_equal(p.background.display_name, 'background') assert_equal(str(p.background.unit), 'dimensionless') @@ -73,7 +73,7 @@ def test_from_pars(self): assert_equal(str(mod.scale.unit), 'dimensionless') assert_equal(mod.scale.value, 2.0) assert_equal(mod.scale.min, 0.0) - assert_equal(mod.scale.max, np.inf) + assert_equal(mod.scale.max, 10.0) assert_equal(mod.scale.fixed, True) assert_equal(mod.background.display_name, 'background') assert_equal(str(mod.background.unit), 'dimensionless') diff --git a/tests/sample/elements/materials/test_material.py b/tests/sample/elements/materials/test_material.py index a9ff1dde..c07a2217 100644 --- a/tests/sample/elements/materials/test_material.py +++ b/tests/sample/elements/materials/test_material.py @@ -5,7 +5,6 @@ __author__ = 'github.com/arm61' __version__ = '0.0.1' -import numpy as np from easyscience import global_object from easyreflectometry.sample.elements.materials.material import DEFAULTS @@ -21,14 +20,14 @@ def test_no_arguments(self): assert p.sld.display_name == 'sld' assert str(p.sld.unit) == '1/Å^2' assert p.sld.value == 4.186 - assert p.sld.min == -np.inf - assert p.sld.max == np.inf + assert p.sld.min == -1.0 + assert p.sld.max == 10.0 assert p.sld.fixed is True assert p.isld.display_name == 'isld' assert str(p.isld.unit) == '1/Å^2' assert p.isld.value == 0.0 - assert p.isld.min == -np.inf - assert p.isld.max == np.inf + assert p.isld.min == -1.0 + assert p.isld.max == 10.0 assert p.isld.fixed is True def test_shuffled_arguments(self): @@ -38,14 +37,14 @@ def test_shuffled_arguments(self): assert p.sld.display_name == 'sld' assert str(p.sld.unit) == '1/Å^2' assert p.sld.value == 6.908 - assert p.sld.min == -np.inf - assert p.sld.max == np.inf + assert p.sld.min == -1.0 + assert p.sld.max == 10.0 assert p.sld.fixed is True assert p.isld.display_name == 'isld' assert str(p.isld.unit) == '1/Å^2' assert p.isld.value == -0.278 - assert p.isld.min == -np.inf - assert p.isld.max == np.inf + assert p.isld.min == -1.0 + assert p.isld.max == 10.0 assert p.isld.fixed is True def test_only_sld_key(self): @@ -53,8 +52,8 @@ def test_only_sld_key(self): assert p.sld.display_name == 'sld' assert str(p.sld.unit) == '1/Å^2' assert p.sld.value == 10 - assert p.sld.min == -np.inf - assert p.sld.max == np.inf + assert p.sld.min == -1.0 + assert p.sld.max == 10.0 assert p.sld.fixed is True def test_only_sld_key_parameter(self): @@ -69,8 +68,8 @@ def test_only_isld_key(self): assert p.isld.display_name == 'isld' assert str(p.isld.unit) == '1/Å^2' assert p.isld.value == 10 - assert p.isld.min == -np.inf - assert p.isld.max == np.inf + assert p.isld.min == -1.0 + assert p.isld.max == 10.0 assert p.isld.fixed is True def test_only_isld_key_parameter(self): diff --git a/tests/test_limits.py b/tests/test_limits.py new file mode 100644 index 00000000..e8320eb7 --- /dev/null +++ b/tests/test_limits.py @@ -0,0 +1,150 @@ +import numpy as np +import pytest +from easyscience import global_object +from easyscience.variable import Parameter + +from easyreflectometry.limits import SCALE_LIMITS +from easyreflectometry.limits import SLD_LIMITS +from easyreflectometry.limits import apply_default_limits + + +class TestApplyDefaultLimits: + def test_sld_with_inf_bounds(self): + param = Parameter('sld', 4.186, min=-np.inf, max=np.inf) + apply_default_limits(param, 'sld') + assert param.min == SLD_LIMITS[0] + assert param.max == SLD_LIMITS[1] + + def test_isld_with_inf_bounds(self): + param = Parameter('isld', 0.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'isld') + assert param.min == SLD_LIMITS[0] + assert param.max == SLD_LIMITS[1] + + def test_sld_preserves_finite_bounds(self): + param = Parameter('sld', 4.0, min=-2.0, max=8.0) + apply_default_limits(param, 'sld') + assert param.min == -2.0 + assert param.max == 8.0 + + def test_scale_with_inf_bounds(self): + param = Parameter('scale', 1.0, min=0, max=np.inf) + apply_default_limits(param, 'scale') + assert param.min == SCALE_LIMITS[0] + assert param.max == SCALE_LIMITS[1] + + def test_scale_preserves_finite_bounds(self): + param = Parameter('scale', 1.0, min=0.5, max=2.0) + apply_default_limits(param, 'scale') + assert param.min == 0.5 + assert param.max == 2.0 + + def test_thickness_percentage_limits(self): + param = Parameter('thickness', 10.0, min=0.0, max=np.inf) + apply_default_limits(param, 'thickness') + assert param.min == 0.0 # 0.0 is finite, not overwritten + assert param.max == 20.0 # 2.0 * 10.0 + + def test_thickness_both_inf(self): + param = Parameter('thickness', 10.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'thickness') + assert param.min == 5.0 # 0.5 * 10.0 + assert param.max == 20.0 # 2.0 * 10.0 + + def test_roughness_percentage_limits(self): + param = Parameter('roughness', 3.3, min=0.0, max=np.inf) + apply_default_limits(param, 'roughness') + assert param.min == 0.0 # 0.0 is finite, not overwritten + assert param.max == pytest.approx(6.6) # 2.0 * 3.3 + + def test_thickness_zero_value_unchanged(self): + param = Parameter('thickness', 0.0, min=0.0, max=np.inf) + apply_default_limits(param, 'thickness') + assert param.min == 0.0 + assert param.max == np.inf # unchanged, zero-valued skip + + def test_roughness_zero_value_unchanged(self): + param = Parameter('roughness', 0.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'roughness') + assert param.min == -np.inf + assert param.max == np.inf + + def test_thickness_preserves_finite_bounds(self): + param = Parameter('thickness', 10.0, min=2.0, max=25.0) + apply_default_limits(param, 'thickness') + assert param.min == 2.0 + assert param.max == 25.0 + + def test_dependent_parameter_skipped(self): + independent_param = Parameter('sld_main', 4.0, min=-np.inf, max=np.inf) + dependent_param = Parameter('sld_dep', 4.0, min=-np.inf, max=np.inf) + dependent_param.make_dependent_on(dependency_expression='a', dependency_map={'a': independent_param}) + apply_default_limits(dependent_param, 'sld') + assert np.isinf(dependent_param.min) + assert np.isinf(dependent_param.max) + + def test_unknown_kind_is_noop(self): + param = Parameter('foo', 5.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'unknown') + assert np.isinf(param.min) + assert np.isinf(param.max) + + +class TestIntegrationWithConstructors: + def setup_method(self): + global_object.map._clear() + + def test_material_gets_sld_limits(self): + from easyreflectometry.sample.elements.materials.material import Material + + mat = Material(sld=6.36, isld=0.0) + assert mat.sld.min == SLD_LIMITS[0] + assert mat.sld.max == SLD_LIMITS[1] + assert mat.isld.min == SLD_LIMITS[0] + assert mat.isld.max == SLD_LIMITS[1] + + def test_layer_gets_percentage_limits(self): + from easyreflectometry.project import Project + + project = Project() + project.default_model() + layer = project.models[0].sample[1].layers[0] + assert layer.thickness.min == 50.0 + assert layer.thickness.max == 200.0 + assert layer.roughness.min == 1.5 + assert layer.roughness.max == 6.0 + + def test_layer_constructor_keeps_default_bounds_until_project_sync(self): + from easyreflectometry.sample.elements.layers.layer import Layer + + layer = Layer(thickness=20.0, roughness=5.0) + assert layer.thickness.min == 0.0 + assert layer.thickness.max == np.inf + assert layer.roughness.min == 0.0 + assert layer.roughness.max == np.inf + + def test_layer_zero_thickness_unchanged(self): + from easyreflectometry.project import Project + + project = Project() + project.default_model() + layer = project.models[0].sample[0].layers[0] + assert layer.thickness.min == 0.0 + assert layer.thickness.max == np.inf + assert layer.roughness.min == 0.0 + assert layer.roughness.max == np.inf + + def test_model_gets_scale_limits(self): + from easyreflectometry.model.model import Model + + model = Model(scale=1.0) + assert model.scale.min == SCALE_LIMITS[0] + assert model.scale.max == SCALE_LIMITS[1] + + def test_existing_parameter_bounds_preserved(self): + from easyreflectometry.sample.elements.materials.material import Material + + custom_sld = Parameter('sld', 4.0, min=-0.5, max=7.0) + mat = Material(sld=custom_sld) + assert mat.sld.min == -0.5 + assert mat.sld.max == 7.0 diff --git a/tests/test_project.py b/tests/test_project.py index 3876e4b8..3c390960 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -720,6 +720,35 @@ def test_parameters(self): assert len(parameters) == 14 assert isinstance(parameters[0], Parameter) + def test_parameters_enabled_flags(self): + global_object.map._clear() + project = Project() + project.default_model() + + sample = project.models[0].sample + superphase = sample.superphase + subphase = sample.subphase + middle_layer = sample[1].front_layer + + assert superphase.thickness.enabled is False + assert superphase.roughness.enabled is False + assert subphase.thickness.enabled is False + assert getattr(subphase.roughness, 'enabled', True) is True + assert getattr(middle_layer.thickness, 'enabled', True) is True + assert getattr(middle_layer.roughness, 'enabled', True) is True + + def test_parameters_read_does_not_overwrite_enabled_flag(self): + global_object.map._clear() + project = Project() + project.default_model() + + parameter = project.models[0].sample[0].layers[0].thickness + parameter.enabled = True + + _ = project.parameters + + assert parameter.enabled is True + def test_current_experiment_index_getter_and_setter(self): global_object.map._clear() project = Project() From 303d6aa95f9deb1c8fd930fab67e3a09a5cc6dfb Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Mon, 27 Apr 2026 14:25:18 +0200 Subject: [PATCH 03/22] Mighell transform (#303) * initial implementation of the mighell algorithm for data with zero variances * don't fail on codecov upload * fixed chi2 reporting, added MD file with description * unit test update * added docs about Mighell * updated easyscience branch, deleted script * chi -> chi2 * use develop for core --- CHANGELOG.md | 9 + docs/src/api/api.rst | 9 + docs/src/api/fitting.rst | 112 ++++ notebooks/zero_variance_fitting.ipynb | 724 ++++++++++++++++++++++++++ pyproject.toml | 3 +- src/easyreflectometry/fitting.py | 318 +++++++++-- tests/test_fitting.py | 454 +++++++++++++++- 7 files changed, 1557 insertions(+), 72 deletions(-) create mode 100644 docs/src/api/fitting.rst create mode 100644 notebooks/zero_variance_fitting.ipynb diff --git a/CHANGELOG.md b/CHANGELOG.md index bb6a1617..b786ccd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# Version 1.4.0 (unreleased) + +Add Mighell-based handling of zero-variance points in fitting (issue #256). +Zero-variance data points are no longer forcibly discarded; instead, a hybrid +objective applies a Mighell substitution for zero-variance points while using +standard weighted least squares for the rest. The previous masking behavior is +available via `objective='legacy_mask'`. New `objective` parameter on +`MultiFitter`, `fit()`, and `fit_single_data_set_1d()`. + # Version 1.3.3 (17 June 2025) Added Chi^2 and fit status to fitting results. diff --git a/docs/src/api/api.rst b/docs/src/api/api.rst index ea8e2661..55bd611a 100644 --- a/docs/src/api/api.rst +++ b/docs/src/api/api.rst @@ -28,6 +28,15 @@ Project provides a higher-level interface for managing models, experiments, and project +Fitting +======= +Fitting helpers and objective functions. + +.. toctree:: + :maxdepth: 1 + + fitting + Assemblies ========== Assemblies are collections of layers that are used to represent a specific physical setup. diff --git a/docs/src/api/fitting.rst b/docs/src/api/fitting.rst new file mode 100644 index 00000000..f5748e59 --- /dev/null +++ b/docs/src/api/fitting.rst @@ -0,0 +1,112 @@ +Fitting +======= + +.. currentmodule:: easyreflectometry.fitting + +Objective functions and zero-variance handling +---------------------------------------------- + +:class:`MultiFitter` supports several objective modes for handling reflectometry +data during fitting, especially when measured variances are zero or invalid. + +The default objective is ``hybrid``. This uses ordinary weighted least squares +for points with positive variance and applies a Mighell-style substitution only +to points whose variance is zero or invalid. The older ``legacy_mask`` mode +drops zero-variance points before fitting. The ``mighell`` mode applies the +Mighell transform to every point. + +Mighell objective +~~~~~~~~~~~~~~~~~ + +The full ``mighell`` objective follows the algebraic form of the +``chi^2_gamma`` statistic described by Mighell for Poisson-distributed count +data: + +.. math:: + + \chi^2_\gamma = + \sum_i \frac{[n_i + \min(n_i, 1) - m_i]^2}{n_i + 1} + +where ``n_i`` are observed counts and ``m_i`` are model values. + +In EasyReflectometry this is implemented as a weighted least-squares problem. +For each observed value ``y_i`` the fitted target is shifted to + +.. math:: + + y_{\mathrm{eff},i} = y_i + \min(y_i, 1) + +and the effective uncertainty is + +.. math:: + + \sigma_i = \sqrt{y_i + 1} + +so the minimized objective is + +.. math:: + + \sum_i \left(\frac{y_{\mathrm{eff},i} - f_i}{\sigma_i}\right)^2 = + \sum_i \frac{[y_i + \min(y_i, 1) - f_i]^2}{y_i + 1} + +This is the same algebraic form as Mighell's statistic, with the model value +``f_i`` replacing ``m_i``. + +Scope and interpretation +~~~~~~~~~~~~~~~~~~~~~~~~ + +Mighell's statistic was derived for Poisson-distributed count data. In +reflectometry workflows, the fitted values are usually normalized +reflectivities or intensities rather than raw counts. They may already have +been processed, scaled, background-corrected, or otherwise transformed before +they reach the fitter. + +This distinction matters when interpreting the result. The full ``mighell`` +objective is not only a reweighting of residuals; it also changes the fitted +target from ``y`` to ``y + min(y, 1)``. For values between zero and one, this +can substantially increase the target value. A fit can therefore have a good +Mighell objective value while looking poorer against the originally plotted +reflectivity curve, or while having a worse classical chi-square. + +For reflectometry data, ``hybrid`` is generally the recommended compromise: +it preserves ordinary weighted least-squares behavior where valid variances are +available, while still allowing zero-variance points to contribute through the +Mighell-style substitution. + +Objective modes +~~~~~~~~~~~~~~~ + +``hybrid`` + Default. Use standard weighted least squares for points with positive + variance and apply the Mighell substitution only where variance is zero or + invalid. + +``mighell`` + Apply the Mighell transform to all points. The reported objective chi-square + is evaluated in transformed objective space and should not be interpreted as + a classical chi-square against the original reflectivity values. + +``legacy_mask`` + Remove zero-variance points before fitting and use standard weighted least + squares for the remaining points. + +``auto`` + Alias for ``hybrid``. + +Fit metrics +~~~~~~~~~~~ + +The fitter exposes both objective-space and classical fit metrics after fitting. +``objective_chi2`` and ``objective_reduced_chi`` describe the minimized +objective, which may include transformed targets under ``hybrid`` or +``mighell``. ``classical_chi2`` and ``classical_reduced_chi`` are computed +against the original observed reflectivity values using only points with +positive variance. + +API reference +------------- + +.. automodule:: easyreflectometry.fitting + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/notebooks/zero_variance_fitting.ipynb b/notebooks/zero_variance_fitting.ipynb new file mode 100644 index 00000000..ea3ede96 --- /dev/null +++ b/notebooks/zero_variance_fitting.ipynb @@ -0,0 +1,724 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a8a52ac", + "metadata": {}, + "source": [ + "# Zero-Variance Handling in Reflectometry Fitting\n", + "\n", + "This notebook demonstrates how `easyreflectometry` handles data points with **zero variance**\n", + "during fitting. We compare three objective strategies:\n", + "\n", + "| Objective | Behaviour |\n", + "|---|---|\n", + "| `legacy_mask` | Drops zero-variance points entirely (old default) |\n", + "| `hybrid` | Keeps all points; applies Mighell substitution only to zero-variance entries (**new default**) |\n", + "| `mighell` | Applies the Mighell (1999) transform to every point |\n", + "\n", + "The experimental data comes from `tests/_static/ref_zero_var.txt`, which contains 192 data points,\n", + "6 of which have zero error (= zero variance)." + ] + }, + { + "cell_type": "markdown", + "id": "5c6429ac", + "metadata": {}, + "source": [ + "## 1. Import Required Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4983acb8", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import warnings\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "from easyreflectometry.calculators import CalculatorFactory\n", + "from easyreflectometry.data.measurement import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", + "from easyreflectometry.sample import Layer\n", + "from easyreflectometry.sample import Material\n", + "from easyreflectometry.sample import Multilayer\n", + "from easyreflectometry.sample import Sample\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "96e174d4", + "metadata": {}, + "source": [ + "## 2. Load Experimental Data\n", + "\n", + "The file `ref_zero_var.txt` is a comma-separated file with columns: `q (Å⁻¹)`, `R`, `error`.\n", + "Several points near the high-Q end have `error = 0.0`, meaning zero variance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47fb3264", + "metadata": {}, + "outputs": [], + "source": [ + "DATA_PATH = os.path.join('..', 'tests', '_static', 'ref_zero_var.txt')\n", + "\n", + "# Load raw data for inspection\n", + "raw = np.loadtxt(DATA_PATH, delimiter=',', comments='#')\n", + "q_raw, r_raw, err_raw = raw[:, 0], raw[:, 1], raw[:, 2]\n", + "\n", + "# Load through easyreflectometry (produces a scipp DataGroup)\n", + "data = load(DATA_PATH)\n", + "data_key = next(iter(data['data'].keys()))\n", + "coord_key = next(iter(data['coords'].keys()))\n", + "result_model_key = f'{data_key}_model'\n", + "\n", + "print(f'Total data points : {len(q_raw)}')\n", + "print(f'Q range : [{q_raw.min():.4e}, {q_raw.max():.4e}] Å⁻¹')\n", + "print(f'R range : [{r_raw.min():.4e}, {r_raw.max():.4e}]')\n", + "print(f'Data key : {data_key}')\n", + "print(f'Coord key : {coord_key}')\n", + "print(f'Model key : {result_model_key}')" + ] + }, + { + "cell_type": "markdown", + "id": "c4495939", + "metadata": {}, + "source": [ + "## 3. Inspect Data and Identify Zero-Variance Points" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1be2ca78", + "metadata": {}, + "outputs": [], + "source": [ + "zero_mask = err_raw == 0.0\n", + "zero_indices = np.where(zero_mask)[0]\n", + "print(f'Number of zero-variance points: {zero_mask.sum()}')\n", + "print(f'Indices: {zero_indices}')\n", + "print('Q-values with zero variance:')\n", + "for idx in zero_indices:\n", + " print(f' [{idx:3d}] Q = {q_raw[idx]:.4e} Å⁻¹, R = {r_raw[idx]:.4e}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "373cdc62", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "# Plot all data\n", + "valid = ~zero_mask\n", + "ax.errorbar(q_raw[valid], r_raw[valid], yerr=err_raw[valid],\n", + " fmt='o', ms=3, color='C0', alpha=0.7, label='Valid points')\n", + "ax.plot(q_raw[zero_mask], r_raw[zero_mask],\n", + " 'rx', ms=10, mew=2, label=f'Zero-variance points ({zero_mask.sum()})')\n", + "\n", + "ax.set_yscale('log')\n", + "ax.set_xlabel('Q (Å⁻¹)')\n", + "ax.set_ylabel('Reflectivity')\n", + "ax.set_title('Raw experimental data — zero-variance points highlighted')\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "428759d3", + "metadata": {}, + "source": [ + "## 4. Define Materials\n", + "\n", + "A simple film-on-substrate structure: **Si** substrate / **SiO₂** native oxide / **Film** / **D₂O** superphase." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "006fb3cf", + "metadata": {}, + "outputs": [], + "source": [ + "si = Material(2.07, 0, 'Si')\n", + "sio2 = Material(3.47, 0, 'SiO2')\n", + "film = Material(2.0, 0, 'Film')\n", + "d2o = Material(6.36, 0, 'D2O')" + ] + }, + { + "cell_type": "markdown", + "id": "6031b9ad", + "metadata": {}, + "source": [ + "## 5. Define Layers and Sample Structure" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2643141f", + "metadata": {}, + "outputs": [], + "source": [ + "si_layer = Layer(si, 0, 0, 'Si layer')\n", + "sio2_layer = Layer(sio2, 30, 3, 'SiO2 layer')\n", + "film_layer = Layer(film, 250, 3, 'Film layer')\n", + "superphase = Layer(d2o, 0, 3, 'D2O superphase')\n", + "\n", + "sample = Sample(\n", + " Multilayer(si_layer),\n", + " Multilayer(sio2_layer),\n", + " Multilayer(film_layer),\n", + " Multilayer(superphase),\n", + " name='Film Structure',\n", + ")\n", + "print(sample)" + ] + }, + { + "cell_type": "markdown", + "id": "51bcedeb", + "metadata": {}, + "source": [ + "## 6. Create the Model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22e6fbd9", + "metadata": {}, + "outputs": [], + "source": [ + "resolution_function = PercentageFwhm(0.02)\n", + "model = Model(sample, 1, 1e-6, resolution_function, 'Film Model')" + ] + }, + { + "cell_type": "markdown", + "id": "7eaf6993", + "metadata": {}, + "source": [ + "## 7. Set Calculator Backend and Compute Initial Curve" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "175afdcc", + "metadata": {}, + "outputs": [], + "source": [ + "interface = CalculatorFactory()\n", + "model.interface = interface\n", + "\n", + "# Compute initial model reflectivity\n", + "r_init = interface.fit_func(q_raw, model.unique_name)" + ] + }, + { + "cell_type": "markdown", + "id": "fff782bb", + "metadata": {}, + "source": [ + "## 8. Plot Initial Model vs Experimental Data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7656b8b", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "ax.errorbar(q_raw[valid], r_raw[valid], yerr=err_raw[valid],\n", + " fmt='o', ms=3, color='C0', alpha=0.6, label='Experiment (valid)')\n", + "ax.plot(q_raw[zero_mask], r_raw[zero_mask],\n", + " 'rx', ms=10, mew=2, label='Experiment (zero variance)')\n", + "ax.plot(q_raw, r_init, '-', color='C1', lw=1.5, label='Initial model')\n", + "\n", + "ax.set_yscale('log')\n", + "ax.set_xlabel('Q (Å⁻¹)')\n", + "ax.set_ylabel('Reflectivity')\n", + "ax.set_title('Experimental data vs initial model (before fitting)')\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "6c916d41", + "metadata": {}, + "source": [ + "## 9. Set Fitting Parameters and Constraints" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a85ab7e8", + "metadata": {}, + "outputs": [], + "source": [ + "sio2_layer.thickness.fixed = False\n", + "sio2_layer.thickness.bounds = (15, 50)\n", + "\n", + "film_layer.thickness.fixed = False\n", + "film_layer.thickness.bounds = (200, 300)\n", + "\n", + "film.sld.fixed = False\n", + "film.sld.bounds = (0.1, 3)\n", + "\n", + "model.background.fixed = False\n", + "model.background.bounds = (1e-7, 1e-5)\n", + "\n", + "model.scale.fixed = False\n", + "model.scale.bounds = (0.5, 1.5)\n", + "\n", + "print('Free parameters:')\n", + "for p in model.get_fit_parameters():\n", + " print(f' {p.name:20s} = {float(p.value):.4g} bounds={p.bounds}')" + ] + }, + { + "cell_type": "markdown", + "id": "b83af903", + "metadata": {}, + "source": [ + "## 10. Zero-Variance Handling — Three Objective Modes\n", + "\n", + "We now fit the same data with each objective mode and compare the results.\n", + "\n", + "### How each mode handles zero-variance points\n", + "\n", + "- **`legacy_mask`** — zero-variance points are dropped before fitting. The fitter sees fewer\n", + " data points, and those Q-values have no influence on the result.\n", + "- **`hybrid`** (default) — valid points use standard weighted least-squares ($w = 1/\\sigma$).\n", + " Zero-variance points get the **Mighell (1999)** substitution:\n", + " $y_\\text{eff} = y + \\min(y, 1)$, $\\sigma = \\sqrt{\\max(y + 1,\\, \\varepsilon)}$.\n", + " This keeps all data in the fit while giving zero-variance points reasonable weight.\n", + "- **`mighell`** — applies the Mighell transform to *every* point, not just zero-variance ones.\n", + " This changes both the weighting and the fitted target for the entire dataset.\n", + "\n", + "Below we report two metric families:\n", + "\n", + "- **objective chi²** — the quantity actually minimized by the selected objective\n", + "- **classical chi²** — a standard variance-weighted chi² computed only on the original\n", + " positive-variance points, for comparison" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8182f0a9", + "metadata": {}, + "outputs": [], + "source": [ + "def build_fresh_model():\n", + " \"\"\"Build a fresh model+interface so each fit starts from the same initial state.\"\"\"\n", + " _si = Material(2.07, 0, 'Si')\n", + " _sio2 = Material(3.47, 0, 'SiO2')\n", + " _film = Material(2.0, 0, 'Film')\n", + " _d2o = Material(6.36, 0, 'D2O')\n", + "\n", + " _si_layer = Layer(_si, 0, 0, 'Si layer')\n", + " _sio2_layer = Layer(_sio2, 30, 3, 'SiO2 layer')\n", + " _film_layer = Layer(_film, 250, 3, 'Film layer')\n", + " _superphase = Layer(_d2o, 0, 3, 'D2O superphase')\n", + "\n", + " _sample = Sample(\n", + " Multilayer(_si_layer),\n", + " Multilayer(_sio2_layer),\n", + " Multilayer(_film_layer),\n", + " Multilayer(_superphase),\n", + " name='Film Structure',\n", + " )\n", + " _resolution = PercentageFwhm(0.02)\n", + " _model = Model(_sample, 1, 1e-6, _resolution, 'Film Model')\n", + "\n", + " _sio2_layer.thickness.fixed = False\n", + " _sio2_layer.thickness.bounds = (15, 50)\n", + " _film_layer.thickness.fixed = False\n", + " _film_layer.thickness.bounds = (200, 300)\n", + " _film.sld.fixed = False\n", + " _film.sld.bounds = (0.1, 3)\n", + " _model.background.fixed = False\n", + " _model.background.bounds = (1e-7, 1e-5)\n", + " _model.scale.fixed = False\n", + " _model.scale.bounds = (0.5, 1.5)\n", + "\n", + " _model.interface = CalculatorFactory()\n", + " return _model" + ] + }, + { + "cell_type": "markdown", + "id": "fd6f4833", + "metadata": {}, + "source": [ + "### 11. Fit with `legacy_mask`\n", + "\n", + "Zero-variance points are simply dropped." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e856e00f", + "metadata": {}, + "outputs": [], + "source": [ + "model_mask = build_fresh_model()\n", + "fitter_mask = MultiFitter(model_mask, objective='legacy_mask')\n", + "\n", + "with warnings.catch_warnings(record=True) as w_mask:\n", + " warnings.simplefilter('always')\n", + " result_mask = fitter_mask.fit(data)\n", + "\n", + "for w in w_mask:\n", + " print(f'[WARNING] {w.message}')\n", + "print(f'Success : {result_mask[\"success\"]}')\n", + "print(f'Objective reduced chi² : {result_mask[\"objective_reduced_chi\"]:.6f}')\n", + "print(f'Objective total chi² : {fitter_mask.objective_chi2:.6f}')\n", + "print(f'Classical reduced chi² : {result_mask[\"classical_reduced_chi\"]:.6f}')\n", + "print(f'Classical total chi² : {fitter_mask.classical_chi2:.6f}')\n", + "\n", + "r_fit_mask = result_mask[result_model_key].values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79755052", + "metadata": {}, + "outputs": [], + "source": [ + "result_mask\n" + ] + }, + { + "cell_type": "markdown", + "id": "24cb6fe0", + "metadata": {}, + "source": [ + "### 12. Fit with `hybrid` (new default)\n", + "\n", + "All points kept; Mighell substitution applied only to zero-variance entries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20c034ba", + "metadata": {}, + "outputs": [], + "source": [ + "model_hybrid = build_fresh_model()\n", + "fitter_hybrid = MultiFitter(model_hybrid, objective='hybrid')\n", + "\n", + "with warnings.catch_warnings(record=True) as w_hybrid:\n", + " warnings.simplefilter('always')\n", + " result_hybrid = fitter_hybrid.fit(data)\n", + "\n", + "for w in w_hybrid:\n", + " print(f'[WARNING] {w.message}')\n", + "print(f'Success : {result_hybrid[\"success\"]}')\n", + "print(f'Objective reduced chi² : {result_hybrid[\"objective_reduced_chi\"]:.6f}')\n", + "print(f'Objective total chi² : {fitter_hybrid.objective_chi2:.6f}')\n", + "print(f'Classical reduced chi² : {result_hybrid[\"classical_reduced_chi\"]:.6f}')\n", + "print(f'Classical total chi² : {fitter_hybrid.classical_chi2:.6f}')\n", + "\n", + "r_fit_hybrid = result_hybrid[result_model_key].values" + ] + }, + { + "cell_type": "markdown", + "id": "79258c5f", + "metadata": {}, + "source": [ + "### 13. Fit with `mighell`\n", + "\n", + "Mighell transform applied to *all* points — the chi² landscape changes entirely." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90b08fdd", + "metadata": {}, + "outputs": [], + "source": [ + "model_mighell = build_fresh_model()\n", + "fitter_mighell = MultiFitter(model_mighell, objective='mighell')\n", + "\n", + "with warnings.catch_warnings(record=True) as w_mighell:\n", + " warnings.simplefilter('always')\n", + " result_mighell = fitter_mighell.fit(data)\n", + "\n", + "for w in w_mighell:\n", + " print(f'[WARNING] {w.message}')\n", + "print(f'Success : {result_mighell[\"success\"]}')\n", + "print(f'Objective reduced chi² : {result_mighell[\"objective_reduced_chi\"]:.6f}')\n", + "print(f'Objective total chi² : {fitter_mighell.objective_chi2:.6f}')\n", + "print(f'Classical reduced chi² : {result_mighell[\"classical_reduced_chi\"]:.6f}')\n", + "print(f'Classical total chi² : {fitter_mighell.classical_chi2:.6f}')\n", + "\n", + "r_fit_mighell = result_mighell[result_model_key].values" + ] + }, + { + "cell_type": "markdown", + "id": "6136693d", + "metadata": {}, + "source": [ + "## 14. Compare Fit Results\n", + "\n", + "### Parameter comparison table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77c23990", + "metadata": {}, + "outputs": [], + "source": [ + "models = {\n", + " 'legacy_mask': model_mask,\n", + " 'hybrid': model_hybrid,\n", + " 'mighell': model_mighell,\n", + "}\n", + "results = {\n", + " 'legacy_mask': result_mask,\n", + " 'hybrid': result_hybrid,\n", + " 'mighell': result_mighell,\n", + "}\n", + "\n", + "# Build descriptive labels to disambiguate duplicates (e.g. two \"thickness\" params)\n", + "ref_params = model_mask.get_fit_parameters()\n", + "seen = {}\n", + "labels = []\n", + "for p in ref_params:\n", + " n = p.name\n", + " seen[n] = seen.get(n, 0) + 1\n", + " labels.append(f'{n} ({seen[n]})')\n", + "# Simplify if name appears only once\n", + "name_counts = {}\n", + "for p in ref_params:\n", + " name_counts[p.name] = name_counts.get(p.name, 0) + 1\n", + "labels_clean = []\n", + "seen2 = {}\n", + "for p in ref_params:\n", + " n = p.name\n", + " seen2[n] = seen2.get(n, 0) + 1\n", + " if name_counts[n] > 1:\n", + " labels_clean.append(f'{n}_{seen2[n]}')\n", + " else:\n", + " labels_clean.append(n)\n", + "\n", + "obj_keys = ['legacy_mask', 'hybrid', 'mighell']\n", + "\n", + "header = f'{\"Parameter\":<24s} {\"legacy_mask\":>14s} {\"hybrid\":>14s} {\"mighell\":>14s}'\n", + "print(header)\n", + "print('-' * len(header))\n", + "\n", + "for i, label in enumerate(labels_clean):\n", + " vals = []\n", + " for obj in obj_keys:\n", + " params = models[obj].get_fit_parameters()\n", + " vals.append(float(params[i].value))\n", + " print(f'{label:<24s} {vals[0]:>14.4g} {vals[1]:>14.4g} {vals[2]:>14.4g}')\n", + "\n", + "print('-' * len(header))\n", + "print(f'{\"objective red. chi²\":<24s} {result_mask[\"objective_reduced_chi\"]:>14.4f} '\n", + " f'{result_hybrid[\"objective_reduced_chi\"]:>14.4f} {result_mighell[\"objective_reduced_chi\"]:>14.6f}')\n", + "print(f'{\"classical red. chi²\":<24s} {result_mask[\"classical_reduced_chi\"]:>14.4f} '\n", + " f'{result_hybrid[\"classical_reduced_chi\"]:>14.4f} {result_mighell[\"classical_reduced_chi\"]:>14.4f}')\n", + "print(f'{\"success\":<24s} {str(result_mask[\"success\"]):>14s} '\n", + " f'{str(result_hybrid[\"success\"]):>14s} {str(result_mighell[\"success\"]):>14s}')" + ] + }, + { + "cell_type": "markdown", + "id": "906b9cdb", + "metadata": {}, + "source": [ + "### Fitted reflectivity curves — all three objectives" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4f8f3a7", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "# Experimental data\n", + "ax.errorbar(\n", + " q_raw[valid],\n", + " r_raw[valid],\n", + " yerr=err_raw[valid],\n", + " fmt='o',\n", + " ms=2,\n", + " color='grey',\n", + " alpha=0.5,\n", + " label='Experiment',\n", + ")\n", + "ax.plot(q_raw[zero_mask], r_raw[zero_mask], 'rx', ms=10, mew=2, label='Zero-variance points')\n", + "\n", + "# Fitted curves\n", + "ax.plot(\n", + " q_raw,\n", + " r_fit_mask,\n", + " '-',\n", + " lw=1.5,\n", + " label=(\n", + " f'legacy_mask (obj={result_mask[\"objective_reduced_chi\"]:.3g}, '\n", + " f'class={result_mask[\"classical_reduced_chi\"]:.3g})'\n", + " ),\n", + ")\n", + "ax.plot(\n", + " q_raw,\n", + " r_fit_hybrid,\n", + " '--',\n", + " lw=1.5,\n", + " label=(\n", + " f'hybrid (obj={result_hybrid[\"objective_reduced_chi\"]:.3g}, '\n", + " f'class={result_hybrid[\"classical_reduced_chi\"]:.3g})'\n", + " ),\n", + ")\n", + "ax.plot(\n", + " q_raw,\n", + " r_fit_mighell,\n", + " ':',\n", + " lw=1.5,\n", + " label=(\n", + " f'mighell (obj={result_mighell[\"objective_reduced_chi\"]:.3g}, '\n", + " f'class={result_mighell[\"classical_reduced_chi\"]:.3g})'\n", + " ),\n", + ")\n", + "\n", + "ax.set_yscale('log')\n", + "ax.set_xlabel('Q (Å⁻¹)')\n", + "ax.set_ylabel('Reflectivity')\n", + "ax.set_title('Fitted reflectivity — comparison of objective modes')\n", + "ax.legend(fontsize=9)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "52821f2d", + "metadata": {}, + "source": [ + "## 15. Examine Residuals\n", + "\n", + "We compute normalised residuals $(R_\\text{exp} - R_\\text{model}) / \\sigma$ for each objective.\n", + "Zero-variance points are shown separately — for `legacy_mask` they were excluded from\n", + "the fit, while `hybrid` and `mighell` included them with transformed weights." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0292ef11", + "metadata": {}, + "outputs": [], + "source": [ + "fig, axes = plt.subplots(3, 1, figsize=(10, 10), sharex=True)\n", + "\n", + "fits = {\n", + " 'legacy_mask': r_fit_mask,\n", + " 'hybrid': r_fit_hybrid,\n", + " 'mighell': r_fit_mighell,\n", + "}\n", + "\n", + "for ax, (obj_name, r_fit) in zip(axes, fits.items()):\n", + " # Normalised residuals for valid points\n", + " residuals_valid = (r_raw[valid] - r_fit[valid]) / err_raw[valid]\n", + " ax.plot(q_raw[valid], residuals_valid, 'o', ms=2, alpha=0.6, color='C0', label='Valid points')\n", + "\n", + " # Un-normalised residuals at zero-variance points (no sigma to normalise by)\n", + " residuals_zero = r_raw[zero_mask] - r_fit[zero_mask]\n", + " ax.plot(q_raw[zero_mask], np.zeros_like(residuals_zero), 'rx', ms=10, mew=2,\n", + " label='Zero-var Q positions')\n", + "\n", + " ax.axhline(0, color='k', lw=0.5)\n", + " ax.set_ylabel('Normalised residual')\n", + " ax.set_title(f'{obj_name}')\n", + " ax.legend(fontsize=8, loc='upper right')\n", + "\n", + "axes[-1].set_xlabel('Q (Å⁻¹)')\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "a2f39948", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "| Objective | Zero-var handling | Objective chi² interpretation | Classical chi² comparison |\n", + "|---|---|---|---|\n", + "| `legacy_mask` | Dropped from fit | Same as classical chi² on retained points | Directly comparable |\n", + "| `hybrid` | Mighell substitution for zero-var only | Slightly modified objective | Usually close to classical when zero-var fraction is small |\n", + "| `mighell` | Mighell transform for **all** points | **Not** a classical chi²; target and weights both change | Can look visibly worse against plotted reflectivity even when the objective is minimized well |\n", + "\n", + "The `hybrid` mode (new default) is recommended: it keeps all data points in the fit while\n", + "preserving a classical chi² comparison on the original positive-variance points.\n", + "\n", + "The full `mighell` mode matches the Mighell paper's objective mathematically, but that paper is\n", + "derived for Poisson count data. Applied to normalized reflectivity, it should be interpreted as a\n", + "Poisson-style objective rather than a visually comparable reduced chi² fit." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "era", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index 9833bc40..b8d0df2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,8 @@ classifiers = [ requires-python = ">=3.11,<3.14" dependencies = [ - "easyscience", + #"easyscience", + "easyscience @ git+https://github.com/EasyScience/core.git@develop", "scipp", "refnx", "refl1d>=1.0.0", diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 86df41e3..0750beb5 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -11,14 +11,145 @@ from easyreflectometry.data import DataSet1D from easyreflectometry.model import Model +_VALID_OBJECTIVES = ('legacy_mask', 'mighell', 'hybrid', 'auto') +_EPS = 1e-30 + + +def _validate_objective(objective: str) -> str: + """Validate and resolve the objective string. + + :param objective: The objective mode string. + :type objective: str + :return: Resolved objective string ('auto' becomes 'hybrid'). + :rtype: str + :raises ValueError: If the objective is not one of the valid options. + """ + if objective not in _VALID_OBJECTIVES: + raise ValueError(f'Unknown objective {objective!r}. Valid options: {_VALID_OBJECTIVES}') + if objective == 'auto': + return 'hybrid' + return objective + + +def _prepare_fit_arrays( + x_vals: np.ndarray, + y_vals: np.ndarray, + variances: np.ndarray, + objective: str, +) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]: + """Prepare x, y_eff, and weights arrays for fitting based on the objective mode. + + For ``legacy_mask``, zero-variance points are removed from all arrays. + For ``hybrid``, valid-variance points use standard WLS while zero-variance + points use Mighell-transformed y and weights. + For ``mighell``, all points use the Mighell transform. + + Note: ``variances`` here means σ² (the scipp convention), not σ. + + :param x_vals: Independent variable values. + :type x_vals: np.ndarray + :param y_vals: Observed dependent variable values. + :type y_vals: np.ndarray + :param variances: Variance (σ²) of each observed point. + :type variances: np.ndarray + :param objective: One of 'legacy_mask', 'hybrid', 'mighell'. + :type objective: str + :return: Tuple of (x_out, y_eff, weights, stats) where stats is a dict + with keys 'valid', 'mighell_substituted', 'masked'. + :rtype: tuple[np.ndarray, np.ndarray, np.ndarray, dict] + """ + n = len(y_vals) + zero_mask = variances <= 0.0 + n_zero = int(np.sum(zero_mask)) + n_valid = n - n_zero + + if objective == 'legacy_mask': + valid = ~zero_mask + x_out = x_vals[valid] + y_eff = y_vals[valid] + if n_valid > 0: + weights = 1.0 / np.sqrt(variances[valid]) + else: + weights = np.array([]) + stats = {'valid': n_valid, 'mighell_substituted': 0, 'masked': n_zero, 'transformed_all_points': False} + return x_out, y_eff, weights, stats + + # hybrid or mighell + y_eff = np.copy(y_vals) + sigma = np.empty(n) + + if objective == 'mighell': + apply_mighell = np.ones(n, dtype=bool) + else: + # hybrid: apply Mighell only to zero-variance points + apply_mighell = zero_mask + + # Standard WLS for non-Mighell points + standard = ~apply_mighell + if np.any(standard): + sigma[standard] = np.sqrt(variances[standard]) + + # Mighell transform for selected points + if np.any(apply_mighell): + y_m = y_vals[apply_mighell] + delta = np.minimum(y_m, 1.0) + y_eff[apply_mighell] = y_m + delta + sigma[apply_mighell] = np.sqrt(np.maximum(y_m + 1.0, _EPS)) + + weights = 1.0 / sigma + n_mighell = int(np.sum(apply_mighell)) + stats = { + 'valid': n - n_mighell, + 'mighell_substituted': n_mighell, + 'masked': 0, + 'transformed_all_points': bool(objective == 'mighell'), + } + return x_vals, y_eff, weights, stats + + +def _compute_weighted_chi2(y_obs: np.ndarray, y_calc: np.ndarray, sigma: np.ndarray) -> float: + """Return weighted chi-square for finite, strictly positive uncertainties.""" + valid = np.isfinite(y_obs) & np.isfinite(y_calc) & np.isfinite(sigma) & (sigma > 0.0) + if not np.any(valid): + return 0.0 + residual = (y_obs[valid] - y_calc[valid]) / sigma[valid] + return float(np.sum(residual**2)) + + +def _compute_reduced_chi2(chi2: float, n_points: int, n_params: int) -> float | None: + """Return reduced chi-square or None when degrees of freedom are not positive.""" + dof = int(n_points) - int(n_params) + if dof <= 0: + return None + return float(chi2 / dof) + + +def _fit_result_reduced_chi(result: FitResults, n_points: int | None = None) -> float: + """Return reduced chi-square from either supported FitResults attribute name.""" + for attribute in ('reduced_chi', 'reduced_chi2'): + value = getattr(result, attribute, None) + if isinstance(value, (int, float, np.number)): + return float(value) + if n_points is not None: + reduced_chi = _compute_reduced_chi2(float(result.chi2), n_points, result.n_pars) + if reduced_chi is not None: + return reduced_chi + raise AttributeError('FitResults object has neither reduced_chi nor reduced_chi2') + class MultiFitter: - def __init__(self, *args: Model): - r"""A convinence class for the :py:class:`easyscience.Fitting.Fitting` + def __init__(self, *args: Model, objective: str = 'hybrid'): + r"""A convenience class for the :py:class:`easyscience.Fitting.Fitting` which will populate the :py:class:`sc.DataGroup` appropriately after the fitting is performed. - :param args: Reflectometry model + :param args: Reflectometry model(s). + :param objective: Zero-variance handling strategy. One of + ``'hybrid'`` (default, Mighell for zero-variance, WLS otherwise), + ``'mighell'`` (Mighell transform for all points), + ``'legacy_mask'`` (drop zero-variance points), + ``'auto'`` (alias for ``'hybrid'``). + :type objective: str """ # This lets the unique_name be passed with the fit_func. @@ -32,22 +163,35 @@ def wrapped(*args, **kwargs): self._models = args self.easy_science_multi_fitter = EasyScienceMultiFitter(args, self._fit_func) self._fit_results: list[FitResults] | None = None - - def fit(self, data: sc.DataGroup, id: int = 0) -> sc.DataGroup: + self._classical_fit_metrics: list[dict] | None = None + self._objective = _validate_objective(objective) + + def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup: + """Perform the fitting and populate the DataGroups with the result. + + :param data: DataGroup to be fitted to and populated. + :type data: sc.DataGroup + :param id: Unused parameter kept for backward compatibility. + :type id: int + :param objective: Per-call override for the zero-variance objective. + If ``None``, uses the instance default set at construction. + :type objective: str or None + :return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics. + :rtype: sc.DataGroup + + :note: Under the ``mighell`` objective all points are transformed, + so ``reduced_chi`` is not a classical chi-square statistic. + Under ``hybrid``, only zero-variance points are transformed; + when they are a small fraction of the data the chi-square + remains approximately classical. """ - Perform the fitting and populate the DataGroups with the result. - - :param data: DataGroup to be fitted to and populated - :param method: Optimisation method + obj = _validate_objective(objective) if objective is not None else self._objective - :note: Points with zero variance in the data will be automatically masked - out during fitting. A warning will be issued if any such points - are found, indicating the number of points masked per reflectivity. - """ refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]] x = [] y = [] dy = [] + original_arrays = [] # Process each reflectivity dataset for i in refl_nums: @@ -55,34 +199,38 @@ def fit(self, data: sc.DataGroup, id: int = 0) -> sc.DataGroup: y_vals = data['data'][f'R_{i}'].values variances = data['data'][f'R_{i}'].variances - # Find points with non-zero variance - zero_variance_mask = variances == 0.0 - num_zero_variance = np.sum(zero_variance_mask) + x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj) - if num_zero_variance > 0: + if stats['masked'] > 0: warnings.warn( - f'Masked {num_zero_variance} data point(s) in reflectivity {i} due to zero variance during fitting.', + f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.', + UserWarning, + ) + if stats.get('transformed_all_points'): + warnings.warn( + f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.', + UserWarning, + ) + elif stats['mighell_substituted'] > 0: + warnings.warn( + f'Applied Mighell substitution to {stats["mighell_substituted"]} ' + f'zero-variance point(s) in reflectivity {i} during fitting.', UserWarning, ) - # Keep only points with non-zero variances - valid_mask = ~zero_variance_mask - x_vals_masked = x_vals[valid_mask] - y_vals_masked = y_vals[valid_mask] - variances_masked = variances[valid_mask] - - x.append(x_vals_masked) - y.append(y_vals_masked) - dy.append(1 / np.sqrt(variances_masked)) + x.append(x_out) + y.append(y_eff) + dy.append(weights) + original_arrays.append({'x': x_vals, 'y': y_vals, 'variances': variances}) result = self.easy_science_multi_fitter.fit(x, y, weights=dy) self._fit_results = result + self._classical_fit_metrics = [] new_data = data.copy() for i, _ in enumerate(result): id = refl_nums[i] - new_data[f'R_{id}_model'] = sc.array( - dims=[f'Qz_{id}'], values=self._fit_func[i](data['coords'][f'Qz_{id}'].values) - ) + model_curve = self._fit_func[i](data['coords'][f'Qz_{id}'].values) + new_data[f'R_{id}_model'] = sc.array(dims=[f'Qz_{id}'], values=model_curve) sld_profile = self.easy_science_multi_fitter._fit_objects[i].interface.sld_profile(self._models[i].unique_name) new_data[f'SLD_{id}'] = sc.array(dims=[f'z_{id}'], values=sld_profile[1] * 1e-6, unit=sc.Unit('1/angstrom') ** 2) if 'attrs' in new_data: @@ -90,41 +238,88 @@ def fit(self, data: sc.DataGroup, id: int = 0) -> sc.DataGroup: new_data['coords'][f'z_{id}'] = sc.array( dims=[f'z_{id}'], values=sld_profile[0], unit=(1 / new_data['coords'][f'Qz_{id}'].unit).unit ) - new_data['reduced_chi'] = float(result[i].reduced_chi) + original = original_arrays[i] + sigma_classical = np.sqrt(np.clip(original['variances'], 0.0, None)) + n_classical_points = int(np.sum(original['variances'] > 0.0)) + classical_chi2 = _compute_weighted_chi2(original['y'], model_curve, sigma_classical) + classical_reduced_chi = _compute_reduced_chi2(classical_chi2, n_classical_points, result[i].n_pars) + objective_chi2 = float(result[i].chi2) + objective_reduced_chi = _fit_result_reduced_chi(result[i], np.size(result[i].x)) + + self._classical_fit_metrics.append( + { + 'classical_chi2': classical_chi2, + 'classical_reduced_chi': classical_reduced_chi, + 'objective_chi2': objective_chi2, + 'objective_reduced_chi': objective_reduced_chi, + 'n_classical_points': n_classical_points, + } + ) + + new_data['objective_chi2'] = objective_chi2 + new_data['objective_reduced_chi'] = objective_reduced_chi + new_data['classical_chi2'] = classical_chi2 + new_data['classical_reduced_chi'] = classical_reduced_chi + new_data['reduced_chi'] = objective_reduced_chi new_data['success'] = result[i].success return new_data - def fit_single_data_set_1d(self, data: DataSet1D) -> FitResults: + def fit_single_data_set_1d(self, data: DataSet1D, objective: str | None = None) -> FitResults: + """Perform fitting on a single 1D dataset. + + :param data: The 1D dataset to fit. Note that ``data.ye`` stores + variances (σ²), not standard deviations. + :type data: DataSet1D + :param objective: Per-call override for the zero-variance objective. + If ``None``, uses the instance default set at construction. + :type objective: str or None + :return: Fit results from the minimizer. + :rtype: FitResults """ - Perform the fitting and populate the DataGroups with the result. + obj = _validate_objective(objective) if objective is not None else self._objective - :param data: DataGroup to be fitted to and populated - :param method: Optimisation method - """ x_vals = np.asarray(data.x) y_vals = np.asarray(data.y) variances = np.asarray(data.ye) - zero_variance_mask = variances == 0.0 - num_zero_variance = int(np.sum(zero_variance_mask)) + x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj) - if num_zero_variance > 0: + if stats['masked'] > 0: + warnings.warn( + f'Masked {stats["masked"]} data point(s) in single-dataset fit due to zero variance during fitting.', + UserWarning, + ) + if stats.get('transformed_all_points'): + warnings.warn( + f'Applied Mighell transform to all {len(y_vals)} point(s) in single-dataset fit during fitting.', + UserWarning, + ) + elif stats['mighell_substituted'] > 0: warnings.warn( - f'Masked {num_zero_variance} data point(s) in single-dataset fit due to zero variance during fitting.', + f'Applied Mighell substitution to {stats["mighell_substituted"]} ' + 'zero-variance point(s) in single-dataset fit during fitting.', UserWarning, ) - valid_mask = ~zero_variance_mask - if not np.any(valid_mask): + if obj == 'legacy_mask' and len(x_out) == 0: raise ValueError('Cannot fit single dataset: all points have zero variance.') - x_vals_masked = x_vals[valid_mask] - y_vals_masked = y_vals[valid_mask] - variances_masked = variances[valid_mask] - - weights = 1.0 / np.sqrt(variances_masked) - result = self.easy_science_multi_fitter.fit(x=[x_vals_masked], y=[y_vals_masked], weights=[weights])[0] + result = self.easy_science_multi_fitter.fit(x=[x_out], y=[y_eff], weights=[weights])[0] self._fit_results = [result] + sigma_classical = np.sqrt(np.clip(variances, 0.0, None)) + model_curve = self._fit_func[0](x_vals) + n_classical_points = int(np.sum(variances > 0.0)) + classical_chi2 = _compute_weighted_chi2(y_vals, model_curve, sigma_classical) + classical_reduced_chi = _compute_reduced_chi2(classical_chi2, n_classical_points, result.n_pars) + self._classical_fit_metrics = [ + { + 'classical_chi2': classical_chi2, + 'classical_reduced_chi': classical_reduced_chi, + 'objective_chi2': float(result.chi2), + 'objective_reduced_chi': _fit_result_reduced_chi(result, len(x_out)), + 'n_classical_points': n_classical_points, + } + ] return result @property @@ -149,6 +344,33 @@ def reduced_chi(self) -> float | None: return total_chi2 / total_dof + @property + def classical_chi2(self) -> float | None: + """Classical chi-squared using only points with positive variances.""" + if self._classical_fit_metrics is None: + return None + return float(sum(metric['classical_chi2'] for metric in self._classical_fit_metrics)) + + @property + def classical_reduced_chi(self) -> float | None: + """Reduced classical chi-squared using only points with positive variances.""" + if self._classical_fit_metrics is None or self._fit_results is None: + return None + total_chi2 = self.classical_chi2 + total_points = sum(metric['n_classical_points'] for metric in self._classical_fit_metrics) + n_params = self._fit_results[0].n_pars + return _compute_reduced_chi2(total_chi2, total_points, n_params) + + @property + def objective_chi2(self) -> float | None: + """Objective-space chi-squared returned by the minimizer.""" + return self.chi2 + + @property + def objective_reduced_chi(self) -> float | None: + """Objective-space reduced chi-squared returned by the minimizer.""" + return self.reduced_chi + def switch_minimizer(self, minimizer: AvailableMinimizers) -> None: """ Switch the minimizer for the fitting. diff --git a/tests/test_fitting.py b/tests/test_fitting.py index 446f10b9..2a03a98c 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -5,6 +5,7 @@ import numpy as np import pytest +import scipp as sc from easyscience.fitting.minimizers.factory import AvailableMinimizers import easyreflectometry @@ -12,6 +13,8 @@ from easyreflectometry.data import DataSet1D from easyreflectometry.data.measurement import load from easyreflectometry.fitting import MultiFitter +from easyreflectometry.fitting import _prepare_fit_arrays +from easyreflectometry.fitting import _validate_objective from easyreflectometry.model import Model from easyreflectometry.model import PercentageFwhm from easyreflectometry.sample import Layer @@ -76,7 +79,7 @@ def test_fitting(minimizer): def test_fitting_with_zero_variance(): - """Test that zero variance points are properly detected and masked during fitting when present in the data.""" + """Test that zero variance points are handled via Mighell substitution (hybrid default).""" import warnings import numpy as np @@ -129,26 +132,24 @@ def test_fitting_with_zero_variance(): model.interface = interface fitter = MultiFitter(model) - # Capture warnings during fitting - check if zero variance points still exist in the data - # and are properly handled by the fitting method + # Capture warnings during fitting with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') analysed = fitter.fit(data) - # Check if any zero variance warnings were issued during fitting - fitting_warnings = [str(warning.message) for warning in w if 'zero variance during fitting' in str(warning.message)] + # Under hybrid default, zero variance points trigger Mighell substitution warnings + mighell_warnings = [str(warning.message) for warning in w if 'Mighell substitution' in str(warning.message)] + mask_warnings = [str(warning.message) for warning in w if 'Masked' in str(warning.message)] + + # Hybrid mode should NOT produce mask warnings + assert len(mask_warnings) == 0, f'Unexpected mask warnings under hybrid: {mask_warnings}' - # The fitting method should handle zero variance points gracefully - # If there are any zero variance points remaining in the data, they should be masked - # and a warning should be issued - if len(fitting_warnings) > 0: - # Verify the warning message format and that it mentions masking points - for warning_msg in fitting_warnings: - assert 'Masked' in warning_msg and 'zero variance during fitting' in warning_msg - print(f'Info: {warning_msg}') # Log for debugging + # If there are zero-variance points in the loaded data, Mighell warnings should appear + if len(mighell_warnings) > 0: + for warning_msg in mighell_warnings: + assert 'zero-variance point(s)' in warning_msg # Basic checks that fitting completed - # The keys will be based on the filename, not just '0' model_keys = [k for k in analysed.keys() if k.endswith('_model')] sld_keys = [k for k in analysed.keys() if k.startswith('SLD_')] assert len(model_keys) > 0, f'No model keys found in {list(analysed.keys())}' @@ -157,7 +158,7 @@ def test_fitting_with_zero_variance(): def test_fitting_with_manual_zero_variance(): - """Test the fit method with manually created zero variance points.""" + """Test the fit method with manually created zero variance points using hybrid (default).""" import warnings import numpy as np @@ -217,12 +218,12 @@ def test_fitting_with_manual_zero_variance(): warnings.simplefilter('always') analysed = fitter.fit(data) - # Check that warnings were issued about zero variance points - fitting_warnings = [str(warning.message) for warning in w if 'zero variance during fitting' in str(warning.message)] + # Under hybrid default, should get Mighell substitution warning, not masking + mighell_warnings = [str(warning.message) for warning in w if 'Mighell substitution' in str(warning.message)] + + assert len(mighell_warnings) == 1, f'Expected 1 Mighell warning, got {len(mighell_warnings)}: {mighell_warnings}' + assert '7 zero-variance point(s)' in mighell_warnings[0], f'Unexpected warning content: {mighell_warnings[0]}' - # Should have one warning about the 7 zero variance points (5 + 2) - assert len(fitting_warnings) == 1, f'Expected 1 warning, got {len(fitting_warnings)}: {fitting_warnings}' - assert 'Masked 7 data point(s)' in fitting_warnings[0], f'Unexpected warning content: {fitting_warnings[0]}' # Basic checks that fitting completed despite zero variance points assert 'R_0_model' in analysed.keys() assert 'SLD_0' in analysed.keys() @@ -230,9 +231,10 @@ def test_fitting_with_manual_zero_variance(): def test_fit_single_data_set_1d_masks_zero_variance_points(): + """Legacy mask mode: zero-variance points are dropped.""" model = Model() model.interface = CalculatorFactory() - fitter = MultiFitter(model) + fitter = MultiFitter(model, objective='legacy_mask') captured = {} mock_result = MagicMock() @@ -255,7 +257,7 @@ def _fake_fit(*, x, y, weights): ye=np.array([0.01, 0.0, 0.04]), ) - with pytest.warns(UserWarning, match='Masked 1 data point\(s\) in single-dataset fit'): + with pytest.warns(UserWarning, match='Masked 1 data point\\(s\\) in single-dataset fit'): result = fitter.fit_single_data_set_1d(data) assert result is mock_result @@ -286,9 +288,10 @@ def test_reduced_chi_uses_global_dof_across_fit_results(): def test_fit_single_data_set_1d_all_zero_variance_raises(): + """Legacy mask mode raises when all points have zero variance.""" model = Model() model.interface = CalculatorFactory() - fitter = MultiFitter(model) + fitter = MultiFitter(model, objective='legacy_mask') data = DataSet1D( name='all_zero', @@ -376,3 +379,408 @@ def _fake_fit(*, x, y, weights): assert result is mock_result assert np.allclose(captured['x'][0], np.array([0.01, 0.02, 0.03])) assert np.allclose(captured['y'][0], np.array([1.0, 0.8, 0.6])) + + +# --- New tests for objective-based zero-variance handling --- + + +def test_objective_validation_rejects_unknown_value(): + with pytest.raises(ValueError, match='Unknown objective'): + _validate_objective('bad_value') + + +def test_objective_validation_resolves_auto(): + assert _validate_objective('auto') == 'hybrid' + assert _validate_objective('hybrid') == 'hybrid' + assert _validate_objective('legacy_mask') == 'legacy_mask' + assert _validate_objective('mighell') == 'mighell' + + +def test_prepare_fit_arrays_weights_always_positive_and_finite(): + """Weights must be strictly positive and finite for all inputs and objectives.""" + test_cases = [ + # (y_vals, variances, description) + (np.array([0.0]), np.array([0.0]), 'y=0, var=0'), + (np.array([-0.5]), np.array([0.0]), 'y=-0.5, var=0'), + (np.array([-1.0]), np.array([0.0]), 'y=-1, var=0'), + (np.array([1e6]), np.array([0.0]), 'y=1e6, var=0'), + (np.array([0.5, 0.3, 0.1]), np.array([0.0, 0.0, 0.0]), 'all-zero variances'), + (np.array([0.5, 0.3, 0.1]), np.array([0.01, 0.0, 0.04]), 'mixed variances'), + (np.array([0.0, -0.5, -1.0, 1e6]), np.array([0.0, 0.0, 0.0, 0.0]), 'edge y values'), + ] + + for objective in ('hybrid', 'mighell'): + for y_vals, variances, desc in test_cases: + x = np.arange(len(y_vals), dtype=float) + _, _, weights, _ = _prepare_fit_arrays(x, y_vals, variances, objective) + assert len(weights) == len(y_vals), f'Wrong length for {desc}, {objective}' + assert np.all(weights > 0), f'Non-positive weight for {desc}, {objective}: {weights}' + assert np.all(np.isfinite(weights)), f'Non-finite weight for {desc}, {objective}: {weights}' + + +def test_prepare_fit_arrays_legacy_mask_drops_zero_variance(): + x = np.array([0.01, 0.02, 0.03]) + y = np.array([1.0, 0.8, 0.6]) + var = np.array([0.01, 0.0, 0.04]) + + x_out, y_eff, weights, stats = _prepare_fit_arrays(x, y, var, 'legacy_mask') + + assert np.allclose(x_out, [0.01, 0.03]) + assert np.allclose(y_eff, [1.0, 0.6]) + assert np.allclose(weights, [1.0 / np.sqrt(0.01), 1.0 / np.sqrt(0.04)]) + assert stats == {'valid': 2, 'mighell_substituted': 0, 'masked': 1, 'transformed_all_points': False} + + +def test_prepare_fit_arrays_hybrid_transforms_zero_variance(): + x = np.array([0.01, 0.02, 0.03]) + y = np.array([1.0, 0.8, 0.6]) + var = np.array([0.01, 0.0, 0.04]) + + x_out, y_eff, weights, stats = _prepare_fit_arrays(x, y, var, 'hybrid') + + # x unchanged + assert np.allclose(x_out, x) + # Index 0 and 2: standard WLS (unchanged y) + assert y_eff[0] == pytest.approx(1.0) + assert y_eff[2] == pytest.approx(0.6) + assert weights[0] == pytest.approx(1.0 / np.sqrt(0.01)) + assert weights[2] == pytest.approx(1.0 / np.sqrt(0.04)) + # Index 1: Mighell transform — y_eff = y + min(y, 1) = 0.8 + 0.8 = 1.6 + assert y_eff[1] == pytest.approx(0.8 + 0.8) + # sigma = sqrt(y + 1) = sqrt(1.8) + assert weights[1] == pytest.approx(1.0 / np.sqrt(1.8)) + assert stats == {'valid': 2, 'mighell_substituted': 1, 'masked': 0, 'transformed_all_points': False} + + +def test_prepare_fit_arrays_mighell_transforms_all(): + x = np.array([0.01, 0.02]) + y = np.array([0.5, 0.3]) + var = np.array([0.01, 0.04]) # All valid, but mighell transforms everything + + x_out, y_eff, weights, stats = _prepare_fit_arrays(x, y, var, 'mighell') + + assert np.allclose(x_out, x) + # y_eff = y + min(y, 1) = y + y (since y < 1) + assert y_eff[0] == pytest.approx(0.5 + 0.5) + assert y_eff[1] == pytest.approx(0.3 + 0.3) + # sigma = sqrt(y + 1) + assert weights[0] == pytest.approx(1.0 / np.sqrt(1.5)) + assert weights[1] == pytest.approx(1.0 / np.sqrt(1.3)) + assert stats == {'valid': 0, 'mighell_substituted': 2, 'masked': 0, 'transformed_all_points': True} + + +def test_fit_single_data_set_1d_hybrid_keeps_zero_variance_points(): + """Hybrid mode keeps all points (transforms zero-variance ones).""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) # default objective='hybrid' + + captured = {} + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.n_pars = 1 + + def _fake_fit(*, x, y, weights): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + return [mock_result] + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(side_effect=_fake_fit) + + data = DataSet1D( + name='hybrid_test', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.01, 0.0, 0.04]), + ) + + with pytest.warns(UserWarning, match='Mighell substitution'): + result = fitter.fit_single_data_set_1d(data) + + assert result is mock_result + # All 3 points should be passed through (not masked) + assert len(captured['x'][0]) == 3 + assert len(captured['y'][0]) == 3 + assert len(captured['weights'][0]) == 3 + + +def test_fit_single_data_set_1d_mighell_warning_mentions_all_points(): + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective='mighell') + + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.reduced_chi = 0.5 + mock_result.n_pars = 1 + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(return_value=[mock_result]) + fitter._fit_func = [lambda x: np.zeros_like(x)] + + data = DataSet1D( + name='mighell_warning', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.01, 0.02, 0.04]), + ) + + with pytest.warns(UserWarning, match=r'Applied Mighell transform to all 3 point\(s\)'): + fitter.fit_single_data_set_1d(data) + + +def test_classical_and_objective_chi_are_split_for_fit_results(): + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective='mighell') + + fit_result = MagicMock() + fit_result.chi2 = 0.25 + fit_result.reduced_chi = 0.125 + fit_result.n_pars = 1 + fit_result.x = np.array([0.01, 0.02, 0.03]) + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(return_value=[fit_result]) + fitter.easy_science_multi_fitter._fit_objects = [MagicMock(interface=MagicMock())] + fitter.easy_science_multi_fitter._fit_objects[0].interface.sld_profile.return_value = ( + np.array([0.0, 1.0]), + np.array([1.0, 2.0]), + ) + + fitter._models = [MagicMock(unique_name='model_0', as_dict=MagicMock(return_value={'name': 'model_0'}))] + fitter._fit_func = [lambda x: np.array([0.8, 0.75, 0.7])] + + data = sc.DataGroup( + { + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.array([0.01, 0.02, 0.03]), unit=sc.Unit('1/angstrom'))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.array([1.0, 0.9, 0.7]), variances=np.array([0.01, 0.0, 0.04]))}, + 'attrs': {}, + } + ) + + analysed = fitter.fit(data) + + expected_classical_chi2 = ((1.0 - 0.8) / 0.1) ** 2 + ((0.7 - 0.7) / 0.2) ** 2 + expected_classical_reduced = expected_classical_chi2 / (2 - fit_result.n_pars) + + assert analysed['objective_chi2'] == pytest.approx(0.25) + assert analysed['objective_reduced_chi'] == pytest.approx(0.125) + assert analysed['classical_chi2'] == pytest.approx(expected_classical_chi2) + assert analysed['classical_reduced_chi'] == pytest.approx(expected_classical_reduced) + assert fitter.objective_chi2 == pytest.approx(0.25) + assert fitter.objective_reduced_chi == pytest.approx(0.125) + assert fitter.classical_chi2 == pytest.approx(expected_classical_chi2) + assert fitter.classical_reduced_chi == pytest.approx(expected_classical_reduced) + + +def test_fit_single_data_set_1d_all_zero_variance_hybrid_does_not_raise(): + """Hybrid mode handles all-zero-variance data without raising.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) # default objective='hybrid' + + captured = {} + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.n_pars = 1 + + def _fake_fit(*, x, y, weights): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + return [mock_result] + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(side_effect=_fake_fit) + + data = DataSet1D( + name='all_zero_hybrid', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.0, 0.0, 0.0]), + ) + + with pytest.warns(UserWarning, match='Mighell substitution'): + result = fitter.fit_single_data_set_1d(data) + + assert result is mock_result + assert len(captured['x'][0]) == 3 + + +def test_fit_single_data_set_1d_legacy_mask_preserves_old_behavior(): + """Legacy mask mode drops zero-variance points and warns with old message.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective='legacy_mask') + + captured = {} + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.n_pars = 1 + + def _fake_fit(*, x, y, weights): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + return [mock_result] + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(side_effect=_fake_fit) + + data = DataSet1D( + name='legacy_test', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.01, 0.0, 0.04]), + ) + + with pytest.warns(UserWarning, match='Masked 1 data point'): + result = fitter.fit_single_data_set_1d(data) + + assert result is mock_result + assert np.allclose(captured['x'][0], np.array([0.01, 0.03])) + assert np.allclose(captured['y'][0], np.array([1.0, 0.6])) + + +def test_fit_multi_dataset_hybrid_uses_transformed_y_and_weights(): + """Multi-dataset fit with hybrid objective transforms zero-variance points.""" + import scipp as sc + + qz_values = np.linspace(0.01, 0.3, 10) + r_values = np.exp(-qz_values * 50) + variances = np.ones_like(r_values) * 0.01 + variances[3:5] = 0.0 # 2 zero-variance points + + data = sc.DataGroup( + { + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz_values)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r_values, variances=variances)}, + } + ) + + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + captured = {} + + def _fake_fit(x, y, weights): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + mock_r = MagicMock() + mock_r.reduced_chi = 1.0 + mock_r.success = True + mock_r.chi2 = 1.0 + mock_r.n_pars = 1 + mock_r.x = x[0] + return [mock_r] + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(side_effect=_fake_fit) + fitter.easy_science_multi_fitter._fit_objects = [MagicMock()] + fitter.easy_science_multi_fitter._fit_objects[0].interface.sld_profile.return_value = ( + np.linspace(0, 100, 5), + np.ones(5), + ) + + import warnings + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + fitter.fit(data) + + # All 10 points should be present (not masked) + assert len(captured['x'][0]) == 10 + assert len(captured['y'][0]) == 10 + assert len(captured['weights'][0]) == 10 + + # Zero-variance points should have Mighell-transformed y + for idx in [3, 4]: + y_orig = r_values[idx] + expected_y_eff = y_orig + min(y_orig, 1.0) + assert captured['y'][0][idx] == pytest.approx(expected_y_eff) + + # Check that Mighell warning was emitted + mighell_warnings = [str(ww.message) for ww in w if 'Mighell substitution' in str(ww.message)] + assert len(mighell_warnings) == 1 + assert '2 zero-variance point(s)' in mighell_warnings[0] + + +def test_fit_warnings_objective_specific(): + """Verify that each objective mode produces the correct warning type.""" + import warnings + + model = Model() + model.interface = CalculatorFactory() + + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.n_pars = 1 + + data = DataSet1D( + name='warn_test', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.01, 0.0, 0.04]), + ) + + for obj, expected_fragment in [ + ('legacy_mask', 'Masked 1 data point(s)'), + ('hybrid', 'Mighell substitution'), + ('mighell', 'Applied Mighell transform to all 3 point(s)'), + ]: + fitter = MultiFitter(model, objective=obj) + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(return_value=[mock_result]) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + fitter.fit_single_data_set_1d(data) + + matching = [str(ww.message) for ww in w if expected_fragment in str(ww.message)] + assert len(matching) > 0, f'No warning containing {expected_fragment!r} for objective={obj}' + + +def test_multifitter_constructor_rejects_bad_objective(): + model = Model() + model.interface = CalculatorFactory() + with pytest.raises(ValueError, match='Unknown objective'): + MultiFitter(model, objective='nonsense') + + +def test_fit_per_call_objective_override(): + """Per-call objective override in fit_single_data_set_1d works.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective='hybrid') # default + + captured = {} + mock_result = MagicMock() + mock_result.chi2 = 1.0 + mock_result.n_pars = 1 + + def _fake_fit(*, x, y, weights): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + return [mock_result] + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.fit = MagicMock(side_effect=_fake_fit) + + data = DataSet1D( + name='override_test', + x=np.array([0.01, 0.02, 0.03]), + y=np.array([1.0, 0.8, 0.6]), + ye=np.array([0.01, 0.0, 0.04]), + ) + + # Override to legacy_mask — should drop the zero-variance point + with pytest.warns(UserWarning, match='Masked 1 data point'): + fitter.fit_single_data_set_1d(data, objective='legacy_mask') + + assert len(captured['x'][0]) == 2 # one point dropped From b883a607a9b6005b1291eb6c7f9c6c0ad4238aac Mon Sep 17 00:00:00 2001 From: rozyczko Date: Thu, 30 Apr 2026 15:07:10 +0200 Subject: [PATCH 04/22] version bump. dependency fix for release. --- pyproject.toml | 3 +-- src/easyreflectometry/__version__.py | 2 +- tests/test_ort_file.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b8d0df2c..9833bc40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,7 @@ classifiers = [ requires-python = ">=3.11,<3.14" dependencies = [ - #"easyscience", - "easyscience @ git+https://github.com/EasyScience/core.git@develop", + "easyscience", "scipp", "refnx", "refl1d>=1.0.0", diff --git a/src/easyreflectometry/__version__.py b/src/easyreflectometry/__version__.py index 77f1c8e6..51ed7c48 100644 --- a/src/easyreflectometry/__version__.py +++ b/src/easyreflectometry/__version__.py @@ -1 +1 @@ -__version__ = '1.5.0' +__version__ = '1.5.1' diff --git a/tests/test_ort_file.py b/tests/test_ort_file.py index c547b1f5..8ef1de16 100644 --- a/tests/test_ort_file.py +++ b/tests/test_ort_file.py @@ -123,6 +123,7 @@ def fit_model(load_data): fitter1 = MultiFitter(multi_layer_model) fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex) + fitter1.easy_science_multi_fitter.max_evaluations = 3000 analysed = fitter1.fit(data) return analysed From bd263d028455bf308d82d2a7c3d05ef7b4c1aef7 Mon Sep 17 00:00:00 2001 From: rozyczko Date: Thu, 30 Apr 2026 15:15:00 +0200 Subject: [PATCH 05/22] modified release version --- CHANGELOG.md | 2 +- src/easyreflectometry/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b786ccd6..77c95690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Version 1.4.0 (unreleased) +# Version 1.6.0 (1 May 2026) Add Mighell-based handling of zero-variance points in fitting (issue #256). Zero-variance data points are no longer forcibly discarded; instead, a hybrid diff --git a/src/easyreflectometry/__version__.py b/src/easyreflectometry/__version__.py index 51ed7c48..bcd8d54e 100644 --- a/src/easyreflectometry/__version__.py +++ b/src/easyreflectometry/__version__.py @@ -1 +1 @@ -__version__ = '1.5.1' +__version__ = '1.6.0' From f76077395f2a7bf06e13f0953f001e339b5a6e5d Mon Sep 17 00:00:00 2001 From: rozyczko Date: Thu, 30 Apr 2026 16:37:48 +0200 Subject: [PATCH 06/22] updated docs --- CHANGELOG.md | 10 +++++----- docs/src/api/fitting.rst | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c95690..69077f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ # Version 1.6.0 (1 May 2026) -Add Mighell-based handling of zero-variance points in fitting (issue #256). -Zero-variance data points are no longer forcibly discarded; instead, a hybrid -objective applies a Mighell substitution for zero-variance points while using -standard weighted least squares for the rest. The previous masking behavior is -available via `objective='legacy_mask'`. New `objective` parameter on +Add Mighell-based handling of non-positive-variance points in fitting (issue #256). +Non-positive-variance data points are no longer forcibly discarded; instead, a +hybrid objective applies a Mighell substitution for non-positive-variance points +while using standard weighted least squares for the rest. The previous masking +behavior is available via `objective='legacy_mask'`. New `objective` parameter on `MultiFitter`, `fit()`, and `fit_single_data_set_1d()`. # Version 1.3.3 (17 June 2025) diff --git a/docs/src/api/fitting.rst b/docs/src/api/fitting.rst index f5748e59..65e1ba15 100644 --- a/docs/src/api/fitting.rst +++ b/docs/src/api/fitting.rst @@ -3,16 +3,16 @@ Fitting .. currentmodule:: easyreflectometry.fitting -Objective functions and zero-variance handling ----------------------------------------------- +Objective functions and non-positive variance handling +----------------------------------------------------- :class:`MultiFitter` supports several objective modes for handling reflectometry -data during fitting, especially when measured variances are zero or invalid. +data during fitting, especially when measured variances are non-positive. The default objective is ``hybrid``. This uses ordinary weighted least squares for points with positive variance and applies a Mighell-style substitution only -to points whose variance is zero or invalid. The older ``legacy_mask`` mode -drops zero-variance points before fitting. The ``mighell`` mode applies the +to points whose variance is non-positive. The older ``legacy_mask`` mode +drops non-positive-variance points before fitting. The ``mighell`` mode applies the Mighell transform to every point. Mighell objective @@ -69,8 +69,8 @@ Mighell objective value while looking poorer against the originally plotted reflectivity curve, or while having a worse classical chi-square. For reflectometry data, ``hybrid`` is generally the recommended compromise: -it preserves ordinary weighted least-squares behavior where valid variances are -available, while still allowing zero-variance points to contribute through the +it preserves ordinary weighted least-squares behavior where positive variances are +available, while still allowing non-positive-variance points to contribute through the Mighell-style substitution. Objective modes @@ -78,8 +78,8 @@ Objective modes ``hybrid`` Default. Use standard weighted least squares for points with positive - variance and apply the Mighell substitution only where variance is zero or - invalid. + variance and apply the Mighell substitution only where variance is + non-positive. ``mighell`` Apply the Mighell transform to all points. The reported objective chi-square @@ -87,7 +87,7 @@ Objective modes a classical chi-square against the original reflectivity values. ``legacy_mask`` - Remove zero-variance points before fitting and use standard weighted least + Remove non-positive-variance points before fitting and use standard weighted least squares for the remaining points. ``auto`` From 8e552667c17fa1ff83165588361d02a609227be6 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Thu, 30 Apr 2026 17:39:43 +0200 Subject: [PATCH 07/22] include plopp as a doc dependency --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 9833bc40..ec3df724 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,6 +62,7 @@ dev = [ docs = [ "myst_parser", "nbsphinx", + "plopp", "sphinx<=8.1.3", "sphinx_autodoc_typehints", "sphinx_book_theme", From b16ec14864d7ec65ea36c19fa391ac6339ac3355 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Wed, 6 May 2026 11:47:24 +0200 Subject: [PATCH 08/22] Preparations for the release (#350) (#351) * backmerge after 1.6.0 release From d773e7ff56f979776736f46e02fe7520ed149c17 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Tue, 12 May 2026 15:23:41 +0200 Subject: [PATCH 09/22] Apply templates (#353) * initial commit up to and including `pixi run check` step * fixes * updates to pyproject.toml * remade __init__.py * minor fix * a few more fixes * Apply templates with docstrings fixes * Add missing favicon and update SVG assets * moved docs for mkdocs * make "pixi run mkdocs build" and "pixi run nonpy-format-check" work together * try using absolute paths for the wheel * minor fixes * refactor md file headers for docs * minor CR changes * linting * code review fixes * CR fixes * proper globbing * remove __version__ --------- Co-authored-by: Andrew Sazonov --- .badgery.yaml | 72 + .codecov.yml | 10 +- .copier-answers.yml | 30 +- .gitattributes | 2 + .github/actions/download-artifact/action.yml | 50 + .github/actions/github-script/action.yml | 19 + .../actions/setup-easyscience-bot/action.yml | 40 + .github/actions/setup-pixi/action.yml | 44 + .github/actions/upload-artifact/action.yml | 49 + .github/actions/upload-codecov/action.yml | 42 + .github/configs/pages-deployment.json | 6 + .github/configs/rulesets-develop.json | 37 + .github/configs/rulesets-gh-pages.json | 19 + .github/configs/rulesets-master.json | 30 + .github/copilot-instructions.md | 53 +- .github/release-drafter.yml | 32 +- .github/scripts/backmerge-conflict-issue.js | 69 + .github/scripts/publish-dashboard.sh | 77 + .github/workflows/backmerge.yml | 109 + .github/workflows/cleanup.yml | 84 + .github/workflows/codeql-analysis.yml | 72 +- .github/workflows/coverage.yml | 94 + .github/workflows/dashboard.yml | 111 + .github/workflows/docs.yml | 188 + .github/workflows/documentation-build.yml | 66 +- .github/workflows/issues-labels.yml | 149 + .github/workflows/lint-format.yml | 124 + .github/workflows/ossar-analysis.yml | 62 +- .github/workflows/pr-labels.yml | 63 + .github/workflows/pypi-publish.yml | 46 + .github/workflows/pypi-test.yml | 80 + .github/workflows/python-ci.yml | 84 +- .github/workflows/python-package.yml | 42 +- .github/workflows/python-publish.yml | 28 +- .../release-drafter-verify-pr-labels.yml | 18 +- .github/workflows/release-drafter.yml | 1 - .github/workflows/release-notes.yml | 71 + .github/workflows/release-pr.yml | 55 + .github/workflows/security.yml | 93 + .github/workflows/test-trigger.yml | 40 + .github/workflows/test.yml | 306 + .github/workflows/tutorial-tests-trigger.yml | 40 + .github/workflows/tutorial-tests.yml | 60 + .gitignore | 59 +- .pre-commit-config.yaml | 61 + .prettierignore | 32 + CHANGELOG.md | 17 +- CONTRIBUTING.md | 446 + LICENSE | 3 +- README.md | 56 +- codecov.yml | 13 + .../assemblies/gradient_layer.md | 1 + .../api-reference/assemblies/multilayer.md | 1 + .../assemblies/repeating_multilayer.md | 1 + .../assemblies/surfactant_layer.md | 1 + docs/docs/api-reference/data.md | 1 + docs/docs/api-reference/elements/layer.md | 1 + .../elements/layer_area_per_molecule.md | 1 + docs/docs/api-reference/elements/material.md | 1 + .../elements/material_density.md | 1 + .../elements/material_mixture.md | 1 + .../elements/material_solvated.md | 1 + docs/docs/api-reference/fitting.md | 1 + docs/docs/api-reference/index.md | 72 + docs/docs/api-reference/model.md | 1 + docs/docs/api-reference/project.md | 1 + docs/docs/api-reference/sample.md | 1 + docs/docs/assets/images/favicon.png | Bin 0 -> 14318 bytes docs/docs/assets/images/logo_dark.svg | 25 + docs/docs/assets/images/logo_light.svg | 25 + docs/docs/assets/javascripts/extra.js | 27 + docs/docs/assets/javascripts/mathjax.js | 33 + docs/docs/assets/stylesheets/extra.css | 359 + docs/docs/index.md | 21 + docs/docs/installation-and-setup/index.md | 282 + docs/docs/introduction/index.md | 68 + .../advancedfitting/multi_contrast.ipynb | 74 +- .../tutorials/advancedfitting/multiple.ort | 0 .../tutorials/basic/assemblies_library.md | 71 + docs/docs/tutorials/basic/layer_library.md | 69 + docs/docs/tutorials/basic/material_library.md | 78 + docs/docs/tutorials/basic/model.md | 87 + .../tutorials/fitting/d70d2o.ort | 0 docs/{src => docs}/tutorials/fitting/dspc.png | Bin .../tutorials/fitting/eq_monolayer.svg | 0 .../tutorials/fitting/eq_solvated.svg | 0 .../tutorials/fitting/example.ort | 0 .../tutorials/fitting/material_solvated.ipynb | 46 +- .../tutorials/fitting/monolayer.ipynb | 53 +- .../tutorials/fitting/monolayer.png | Bin .../tutorials/fitting/monolayer.svg | 0 .../tutorials/fitting/polymer_film.png | Bin .../tutorials/fitting/polymer_film.svg | 0 .../tutorials/fitting/repeating.ipynb | 42 +- .../tutorials/fitting/repeating.png | Bin .../tutorials/fitting/repeating.svg | 0 .../tutorials/fitting/repeating_layers.ort | 0 .../tutorials/fitting/simple_fitting.ipynb | 45 +- docs/docs/tutorials/index.md | 56 + .../tutorials/simulation/bilayer.ipynb | 59 +- .../tutorials/simulation/magnetism.ipynb | 101 +- .../mod_pointwise_two_layer_sample_dq-0.0.ort | 0 .../mod_pointwise_two_layer_sample_dq-1.0.ort | 0 ...mod_pointwise_two_layer_sample_dq-10.0.ort | 0 .../simulation/resolution_functions.ipynb | 51 +- .../tutorials/simulation/two_layers.png | Bin .../tutorials/simulation/two_layers.svg | 0 docs/docs/user-guide/index.md | 211 + docs/includes/abbreviations.md | 15 + docs/mkdocs.yml | 217 + docs/overrides/.icons/app.svg | 4 + docs/overrides/.icons/easyreflectometry.svg | 16 + docs/overrides/.icons/easyscience.svg | 20 + docs/overrides/.icons/google-colab.svg | 7 + docs/overrides/main.html | 39 + docs/overrides/partials/logo.html | 15 + docs/src/conf.py | 44 +- .../advancedfitting/advancedfitting.rst | 9 - .../tutorials/basic/assemblies_library.rst | 249 - docs/src/tutorials/basic/basic.rst | 13 - docs/src/tutorials/basic/layer_library.rst | 84 - docs/src/tutorials/basic/material_library.rst | 87 - docs/src/tutorials/basic/model.rst | 80 - docs/src/tutorials/extra/extra.rst | 7 - docs/src/tutorials/fitting/fitting.rst | 12 - docs/src/tutorials/simulation/simulation.rst | 11 - docs/src/tutorials/tutorials.rst | 49 - package-lock.json | 65 + package.json | 6 + pixi.lock | 13299 ++++++++++++++++ pixi.toml | 278 + prettierrc.toml | 22 + pyproject.toml | 441 +- src/easyreflectometry/__init__.py | 9 +- src/easyreflectometry/__version__.py | 1 - src/easyreflectometry/calculators/__init__.py | 5 +- .../calculators/bornagain/calculator.py | 98 +- .../calculators/bornagain/wrapper.py | 244 +- .../calculators/calculator_base.py | 118 +- src/easyreflectometry/calculators/factory.py | 8 + .../calculators/refl1d/calculator.py | 9 +- .../calculators/refl1d/wrapper.py | 180 +- .../calculators/refnx/calculator.py | 9 +- .../calculators/refnx/wrapper.py | 166 +- .../calculators/wrapper_base.py | 191 +- src/easyreflectometry/data/__init__.py | 3 + src/easyreflectometry/data/data_store.py | 21 + src/easyreflectometry/data/measurement.py | 15 +- src/easyreflectometry/fitting.py | 160 +- src/easyreflectometry/limits.py | 13 +- src/easyreflectometry/main.py | 4 + src/easyreflectometry/model/__init__.py | 3 + src/easyreflectometry/model/model.py | 84 +- .../model/model_collection.py | 26 +- .../model/resolution_functions.py | 30 +- src/easyreflectometry/orso_utils.py | 42 +- src/easyreflectometry/plot.py | 21 +- src/easyreflectometry/project.py | 210 +- src/easyreflectometry/sample/__init__.py | 3 + .../sample/assemblies/__init__.py | 2 + .../sample/assemblies/base_assembly.py | 39 +- .../sample/assemblies/bilayer.py | 135 +- .../sample/assemblies/gradient_layer.py | 50 +- .../sample/assemblies/multilayer.py | 45 +- .../sample/assemblies/repeating_multilayer.py | 24 +- .../sample/assemblies/surfactant_layer.py | 63 +- src/easyreflectometry/sample/base_core.py | 13 +- .../sample/collections/__init__.py | 2 + .../sample/collections/base_collection.py | 55 +- .../sample/collections/layer_collection.py | 16 +- .../sample/collections/material_collection.py | 18 +- .../sample/collections/sample.py | 56 +- .../sample/elements/__init__.py | 2 + .../sample/elements/layers/__init__.py | 2 + .../sample/elements/layers/layer.py | 29 +- .../layers/layer_area_per_molecule.py | 65 +- .../sample/elements/materials/__init__.py | 2 + .../sample/elements/materials/material.py | 20 +- .../elements/materials/material_density.py | 30 +- .../elements/materials/material_mixture.py | 64 +- .../elements/materials/material_solvated.py | 46 +- src/easyreflectometry/special/calculations.py | 98 +- src/easyreflectometry/special/parsing.py | 66 +- src/easyreflectometry/summary/__init__.py | 5 +- .../summary/html_templates.py | 15 +- src/easyreflectometry/summary/summary.py | 14 + src/easyreflectometry/utils.py | 27 +- .../bornagain/test_bornagain_calculator.py | 5 +- .../bornagain/test_bornagain_wrapper.py | 6 +- .../refl1d/test_refl1d_calculator.py | 6 +- .../calculators/refl1d/test_refl1d_wrapper.py | 6 +- .../refnx/test_refnx_calculator.py | 6 +- tests/calculators/refnx/test_refnx_wrapper.py | 41 +- tests/data/test_data_store.py | 11 +- tests/functional/test_dummy.py | 8 + tests/integration/fitting/test_dummy.py | 17 + .../integration/scipp-analysis/test_dummy.py | 17 + tests/model/test_model.py | 6 +- tests/model/test_model_collection.py | 8 +- tests/model/test_resolution_functions.py | 12 +- tests/package_test.py | 3 +- tests/sample/assemblies/test_base_assembly.py | 3 + tests/sample/assemblies/test_bilayer.py | 4 +- .../sample/assemblies/test_gradient_layer.py | 9 +- tests/sample/assemblies/test_multilayer.py | 6 +- .../assemblies/test_repeating_multilayer.py | 7 +- .../assemblies/test_surfactant_layer.py | 14 +- .../collections/test_base_collection.py | 3 + .../collections/test_layer_collection.py | 6 +- .../collections/test_material_collection.py | 3 + tests/sample/collections/test_sample.py | 7 +- tests/sample/elements/layers/test_layer.py | 6 +- .../layers/test_layer_area_per_molecule.py | 3 + .../elements/materials/test_material.py | 6 +- .../materials/test_material_density.py | 3 + .../materials/test_material_mixture.py | 3 + .../materials/test_material_solvated.py | 3 + tests/special/test_calculations.py | 4 +- tests/summary/test_summary.py | 3 + tests/test_data.py | 10 +- tests/test_fitting.py | 63 +- tests/test_limits.py | 3 + tests/test_measurement_comprehensive.py | 34 +- tests/test_orso_utils.py | 18 +- tests/test_ort_file.py | 5 +- tests/test_parameter_utils.py | 3 + tests/test_project.py | 36 +- tests/test_topmost_nesting.py | 5 +- tests/test_utils.py | 16 +- tests/unit/test_dummy.py | 8 + tools/license_headers.py | 321 + tools/update_docs_assets.py | 91 + tools/update_github_labels.py | 341 + vscode-template/settings.json | 22 +- 234 files changed, 22209 insertions(+), 2201 deletions(-) create mode 100644 .badgery.yaml create mode 100644 .gitattributes create mode 100644 .github/actions/download-artifact/action.yml create mode 100644 .github/actions/github-script/action.yml create mode 100644 .github/actions/setup-easyscience-bot/action.yml create mode 100644 .github/actions/setup-pixi/action.yml create mode 100644 .github/actions/upload-artifact/action.yml create mode 100644 .github/actions/upload-codecov/action.yml create mode 100644 .github/configs/pages-deployment.json create mode 100644 .github/configs/rulesets-develop.json create mode 100644 .github/configs/rulesets-gh-pages.json create mode 100644 .github/configs/rulesets-master.json create mode 100644 .github/scripts/backmerge-conflict-issue.js create mode 100644 .github/scripts/publish-dashboard.sh create mode 100644 .github/workflows/backmerge.yml create mode 100644 .github/workflows/cleanup.yml create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/dashboard.yml create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/issues-labels.yml create mode 100644 .github/workflows/lint-format.yml create mode 100644 .github/workflows/pr-labels.yml create mode 100644 .github/workflows/pypi-publish.yml create mode 100644 .github/workflows/pypi-test.yml create mode 100644 .github/workflows/release-notes.yml create mode 100644 .github/workflows/release-pr.yml create mode 100644 .github/workflows/security.yml create mode 100644 .github/workflows/test-trigger.yml create mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/tutorial-tests-trigger.yml create mode 100644 .github/workflows/tutorial-tests.yml create mode 100644 .pre-commit-config.yaml create mode 100644 .prettierignore create mode 100644 CONTRIBUTING.md create mode 100644 codecov.yml create mode 100644 docs/docs/api-reference/assemblies/gradient_layer.md create mode 100644 docs/docs/api-reference/assemblies/multilayer.md create mode 100644 docs/docs/api-reference/assemblies/repeating_multilayer.md create mode 100644 docs/docs/api-reference/assemblies/surfactant_layer.md create mode 100644 docs/docs/api-reference/data.md create mode 100644 docs/docs/api-reference/elements/layer.md create mode 100644 docs/docs/api-reference/elements/layer_area_per_molecule.md create mode 100644 docs/docs/api-reference/elements/material.md create mode 100644 docs/docs/api-reference/elements/material_density.md create mode 100644 docs/docs/api-reference/elements/material_mixture.md create mode 100644 docs/docs/api-reference/elements/material_solvated.md create mode 100644 docs/docs/api-reference/fitting.md create mode 100644 docs/docs/api-reference/index.md create mode 100644 docs/docs/api-reference/model.md create mode 100644 docs/docs/api-reference/project.md create mode 100644 docs/docs/api-reference/sample.md create mode 100644 docs/docs/assets/images/favicon.png create mode 100644 docs/docs/assets/images/logo_dark.svg create mode 100644 docs/docs/assets/images/logo_light.svg create mode 100644 docs/docs/assets/javascripts/extra.js create mode 100644 docs/docs/assets/javascripts/mathjax.js create mode 100644 docs/docs/assets/stylesheets/extra.css create mode 100644 docs/docs/index.md create mode 100644 docs/docs/installation-and-setup/index.md create mode 100644 docs/docs/introduction/index.md rename docs/{src => docs}/tutorials/advancedfitting/multi_contrast.ipynb (92%) rename docs/{src => docs}/tutorials/advancedfitting/multiple.ort (100%) create mode 100644 docs/docs/tutorials/basic/assemblies_library.md create mode 100644 docs/docs/tutorials/basic/layer_library.md create mode 100644 docs/docs/tutorials/basic/material_library.md create mode 100644 docs/docs/tutorials/basic/model.md rename docs/{src => docs}/tutorials/fitting/d70d2o.ort (100%) rename docs/{src => docs}/tutorials/fitting/dspc.png (100%) rename docs/{src => docs}/tutorials/fitting/eq_monolayer.svg (100%) rename docs/{src => docs}/tutorials/fitting/eq_solvated.svg (100%) rename docs/{src => docs}/tutorials/fitting/example.ort (100%) rename docs/{src => docs}/tutorials/fitting/material_solvated.ipynb (93%) rename docs/{src => docs}/tutorials/fitting/monolayer.ipynb (94%) rename docs/{src => docs}/tutorials/fitting/monolayer.png (100%) rename docs/{src => docs}/tutorials/fitting/monolayer.svg (100%) rename docs/{src => docs}/tutorials/fitting/polymer_film.png (100%) rename docs/{src => docs}/tutorials/fitting/polymer_film.svg (100%) rename docs/{src => docs}/tutorials/fitting/repeating.ipynb (94%) rename docs/{src => docs}/tutorials/fitting/repeating.png (100%) rename docs/{src => docs}/tutorials/fitting/repeating.svg (100%) rename docs/{src => docs}/tutorials/fitting/repeating_layers.ort (100%) rename docs/{src => docs}/tutorials/fitting/simple_fitting.ipynb (96%) create mode 100644 docs/docs/tutorials/index.md rename docs/{src => docs}/tutorials/simulation/bilayer.ipynb (95%) rename docs/{src => docs}/tutorials/simulation/magnetism.ipynb (87%) rename docs/{src => docs}/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort (100%) rename docs/{src => docs}/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort (100%) rename docs/{src => docs}/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort (100%) rename docs/{src => docs}/tutorials/simulation/resolution_functions.ipynb (90%) rename docs/{src => docs}/tutorials/simulation/two_layers.png (100%) rename docs/{src => docs}/tutorials/simulation/two_layers.svg (100%) create mode 100644 docs/docs/user-guide/index.md create mode 100644 docs/includes/abbreviations.md create mode 100644 docs/mkdocs.yml create mode 100644 docs/overrides/.icons/app.svg create mode 100644 docs/overrides/.icons/easyreflectometry.svg create mode 100644 docs/overrides/.icons/easyscience.svg create mode 100644 docs/overrides/.icons/google-colab.svg create mode 100644 docs/overrides/main.html create mode 100644 docs/overrides/partials/logo.html delete mode 100644 docs/src/tutorials/advancedfitting/advancedfitting.rst delete mode 100644 docs/src/tutorials/basic/assemblies_library.rst delete mode 100644 docs/src/tutorials/basic/basic.rst delete mode 100644 docs/src/tutorials/basic/layer_library.rst delete mode 100644 docs/src/tutorials/basic/material_library.rst delete mode 100644 docs/src/tutorials/basic/model.rst delete mode 100644 docs/src/tutorials/extra/extra.rst delete mode 100644 docs/src/tutorials/fitting/fitting.rst delete mode 100644 docs/src/tutorials/simulation/simulation.rst delete mode 100644 docs/src/tutorials/tutorials.rst create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pixi.lock create mode 100644 pixi.toml create mode 100644 prettierrc.toml delete mode 100644 src/easyreflectometry/__version__.py create mode 100644 src/easyreflectometry/sample/assemblies/__init__.py create mode 100644 src/easyreflectometry/sample/collections/__init__.py create mode 100644 src/easyreflectometry/sample/elements/__init__.py create mode 100644 src/easyreflectometry/sample/elements/layers/__init__.py create mode 100644 src/easyreflectometry/sample/elements/materials/__init__.py create mode 100644 tests/functional/test_dummy.py create mode 100644 tests/integration/fitting/test_dummy.py create mode 100644 tests/integration/scipp-analysis/test_dummy.py create mode 100644 tests/unit/test_dummy.py create mode 100644 tools/license_headers.py create mode 100644 tools/update_docs_assets.py create mode 100644 tools/update_github_labels.py diff --git a/.badgery.yaml b/.badgery.yaml new file mode 100644 index 00000000..99bcdc1c --- /dev/null +++ b/.badgery.yaml @@ -0,0 +1,72 @@ +default_branch: master +develop_branch: develop + +cards: + - group: Tests + type: gh_action + title: Code/package tests (GitHub) + file: test.yml + enabled: true + - group: Tests + type: gh_action + title: Tutorial tests (GitHub) + file: tutorial-tests.yml + enabled: true + + - group: Tests + type: gh_action + title: Package tests (PyPI) + file: pypi-test.yml + enabled: true + + - group: Code Quality + type: codefactor + title: Code quality (CodeFactor) + enabled: true + + - group: Code Quality + type: radon_mi + title: Maintainability index (radon) + report: reports/{branch}/maintainability-index.json + enabled: true + + - group: Code Quality + type: radon_cc + title: Cyclomatic complexity (radon) + report: reports/{branch}/cyclomatic-complexity.json + enabled: true + + - group: Size + type: radon_loc + title: Source/Logical lines of code (radon) + report: reports/{branch}/raw-metrics.json + enabled: true + + - group: Size + type: radon_ff + title: Functions/Files count (radon) + report: reports/{branch}/cyclomatic-complexity.json + enabled: true + + - group: Coverage + type: codecov + title: Unit test coverage (Codecov) + flag: unittests + enabled: true + + - group: Coverage + type: interrogate + title: Docstring coverage (interrogate) + report: reports/{branch}/coverage-docstring.txt + enabled: true + - group: Build & Release + type: gh_action + title: Publishing (PyPI) + workflow: pypi-publish.yml + enabled: true + + - group: Build & Release + type: gh_action + title: Docs build/deployment + workflow: docs.yml + enabled: true diff --git a/.codecov.yml b/.codecov.yml index 9c9abf0b..e17376e8 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,8 +1,8 @@ github_checks: - annotations: true + annotations: true comment: - layout: "reach, diff, flags, files" + layout: 'reach, diff, flags, files' behavior: default - require_changes: false # if true: only post the comment if coverage changes - require_base: no # [yes :: must have a base report to post] - require_head: yes # [yes :: must have a head report to post] + require_changes: false # if true: only post the comment if coverage changes + require_base: no # [yes :: must have a base report to post] + require_head: yes # [yes :: must have a head report to post] diff --git a/.copier-answers.yml b/.copier-answers.yml index 867a00e8..f8fbdb26 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,11 +1,19 @@ -# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: 8bdcedc -_src_path: gh:/EasyScience/EasyProjectTemplate -description: A reflectometry python package built on the EasyScience framework. -max_python: '3.13' -min_python: '3.9' -orgname: EasyScience -packagename: easyreflectometry -prettyname: Easy Reflectometry Library -projectname: easyreflectometry -year: 2024 +# WARNING: Do not edit this file manually. +# Any changes will be overwritten by Copier. +_commit: v0.11.2-3-ge3f42a1 +_src_path: gh:easyscience/templates +lib_docs_url: https://easyscience.github.io/reflectometry-lib +lib_doi: 10.5281/zenodo.18163581 +lib_package_name: easyreflectometry +lib_python_max: '3.13' +lib_python_min: '3.11' +lib_repo_name: reflectometry-lib +project_contact_email: support@easyreflectometry.org +project_copyright_years: 2021-2026 +project_extended_description: A software for performing reflectometry calculations + based on a layer model and refining its parameters against reflectometry data +project_name: EasyReflectometry +project_short_description: Reflectometry data analysis +project_shortcut: ER +project_type: lib +template_type: lib diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..997504b4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml new file mode 100644 index 00000000..d1fff1a0 --- /dev/null +++ b/.github/actions/download-artifact/action.yml @@ -0,0 +1,50 @@ +name: 'Download artifact' +description: 'Wrapper for actions/download-artifact' +inputs: + name: + description: 'Name of the artifact to download' + required: true + + path: + description: 'Destination path' + required: false + default: '.' + + pattern: + description: 'Glob pattern to match artifact names (optional)' + required: false + default: '' + + merge-multiple: + description: 'Merge multiple artifacts into the same directory' + required: false + default: 'false' + + github-token: + description: 'GitHub token for cross-repo download (optional)' + required: false + default: '' + + repository: + description: 'owner/repo for cross-repo download (optional)' + required: false + default: '' + + run-id: + description: 'Workflow run ID for cross-run download (optional)' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Download artifact + uses: actions/download-artifact@v8 + with: + name: ${{ inputs.name }} + path: ${{ inputs.path }} + pattern: ${{ inputs.pattern }} + merge-multiple: ${{ inputs.merge-multiple }} + github-token: ${{ inputs.github-token }} + repository: ${{ inputs.repository }} + run-id: ${{ inputs.run-id }} diff --git a/.github/actions/github-script/action.yml b/.github/actions/github-script/action.yml new file mode 100644 index 00000000..50de89b7 --- /dev/null +++ b/.github/actions/github-script/action.yml @@ -0,0 +1,19 @@ +name: 'GitHub Script' +description: 'Wrapper for actions/github-script' +inputs: + script: + description: 'JavaScript to run' + required: true + + github-token: + description: 'GitHub token (defaults to github.token)' + required: false + default: ${{ github.token }} + +runs: + using: 'composite' + steps: + - uses: actions/github-script@v9 + with: + script: ${{ inputs.script }} + github-token: ${{ inputs.github-token }} diff --git a/.github/actions/setup-easyscience-bot/action.yml b/.github/actions/setup-easyscience-bot/action.yml new file mode 100644 index 00000000..e51eb01a --- /dev/null +++ b/.github/actions/setup-easyscience-bot/action.yml @@ -0,0 +1,40 @@ +name: 'Setup EasyScience bot for pushing' +description: 'Create GitHub App token and configure git identity + origin remote' +inputs: + app-id: + description: 'GitHub App ID' + required: true + private-key: + description: 'GitHub App private key (PEM)' + required: true + repositories: + description: 'Additional repositories to grant access to (newline-separated)' + required: false + default: '' + +outputs: + token: + description: 'Installation access token' + value: ${{ steps.app-token.outputs.token }} + +runs: + using: 'composite' + steps: + - name: Create GitHub App installation token + id: app-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ inputs.app-id }} + private-key: ${{ inputs.private-key }} + repositories: ${{ inputs.repositories }} + + - name: Configure git for pushing + shell: bash + run: | + git config user.name "easyscience[bot]" + git config user.email "${{ inputs.app-id }}+easyscience[bot]@users.noreply.github.com" + + - name: Configure origin remote to use the bot token + shell: bash + run: | + git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git diff --git a/.github/actions/setup-pixi/action.yml b/.github/actions/setup-pixi/action.yml new file mode 100644 index 00000000..ec7d7ba7 --- /dev/null +++ b/.github/actions/setup-pixi/action.yml @@ -0,0 +1,44 @@ +name: 'Setup Pixi Environment' +description: 'Wrapper for prefix-dev/setup-pixi' +inputs: + environments: + description: 'Pixi environments to setup' + required: false + default: 'default' + activate-environment: + description: 'Environment to activate' + required: false + default: 'default' + run-install: + description: 'Whether to run pixi install' + required: false + default: 'true' + locked: + description: 'Whether to run pixi install --locked' + required: false + default: 'false' + frozen: + description: 'Whether to run pixi install --frozen' + required: false + default: 'true' + cache: + description: 'Whether to use cache' + required: false + default: 'false' + post-cleanup: + description: 'Whether to run post cleanup' + required: false + default: 'false' + +runs: + using: 'composite' + steps: + - uses: prefix-dev/setup-pixi@v0.9.4 + with: + environments: ${{ inputs.environments }} + activate-environment: ${{ inputs.activate-environment }} + run-install: ${{ inputs.run-install }} + locked: ${{ inputs.locked }} + frozen: ${{ inputs.frozen }} + cache: ${{ inputs.cache }} + post-cleanup: ${{ inputs.post-cleanup }} diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml new file mode 100644 index 00000000..fe8e4680 --- /dev/null +++ b/.github/actions/upload-artifact/action.yml @@ -0,0 +1,49 @@ +name: 'Upload artifact' +description: 'Wrapper for actions/upload-artifact' +inputs: + name: + description: 'Artifact name' + required: true + + path: + description: 'File(s)/dir(s)/glob(s) to upload (newline-separated)' + required: true + + include-hidden-files: + description: 'Include hidden files' + required: false + default: 'true' + + if-no-files-found: + description: 'warn | error | ignore' + required: false + default: 'error' + + compression-level: + description: '0-9 (0 = no compression)' + required: false + default: '0' + + retention-days: + description: 'Retention in days (optional)' + required: false + default: '' + + overwrite: + description: 'Overwrite an existing artifact with the same name' + required: false + default: 'false' + +runs: + using: 'composite' + steps: + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: ${{ inputs.name }} + path: ${{ inputs.path }} + include-hidden-files: ${{ inputs.include-hidden-files }} + if-no-files-found: ${{ inputs.if-no-files-found }} + compression-level: ${{ inputs.compression-level }} + retention-days: ${{ inputs.retention-days }} + overwrite: ${{ inputs.overwrite }} diff --git a/.github/actions/upload-codecov/action.yml b/.github/actions/upload-codecov/action.yml new file mode 100644 index 00000000..0cb15d1f --- /dev/null +++ b/.github/actions/upload-codecov/action.yml @@ -0,0 +1,42 @@ +name: 'Upload coverage to Codecov' +description: 'Wrapper for codecov/codecov-action' + +inputs: + name: + description: 'Codecov upload name' + required: true + + flags: + description: 'Codecov flags' + required: false + default: '' + + files: + description: 'Coverage report files' + required: true + + fail_ci_if_error: + description: 'Fail CI if upload fails' + required: false + default: 'true' + + verbose: + description: 'Enable verbose output' + required: false + default: 'true' + + token: + description: 'Codecov token' + required: true + +runs: + using: composite + steps: + - uses: codecov/codecov-action@v6 + with: + name: ${{ inputs.name }} + flags: ${{ inputs.flags }} + files: ${{ inputs.files }} + fail_ci_if_error: ${{ inputs.fail_ci_if_error }} + verbose: ${{ inputs.verbose }} + token: ${{ inputs.token }} diff --git a/.github/configs/pages-deployment.json b/.github/configs/pages-deployment.json new file mode 100644 index 00000000..c0d3fbee --- /dev/null +++ b/.github/configs/pages-deployment.json @@ -0,0 +1,6 @@ +{ + "source": { + "branch": "gh-pages", + "path": "/" + } +} diff --git a/.github/configs/rulesets-develop.json b/.github/configs/rulesets-develop.json new file mode 100644 index 00000000..04489e52 --- /dev/null +++ b/.github/configs/rulesets-develop.json @@ -0,0 +1,37 @@ +{ + "name": "develop branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["refs/heads/develop"], + "exclude": [] + } + }, + "bypass_actors": [ + { + "actor_id": 2476259, + "actor_type": "Integration", + "bypass_mode": "always" + } + ], + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + }, + { + "type": "pull_request", + "parameters": { + "allowed_merge_methods": ["squash"], + "dismiss_stale_reviews_on_push": false, + "require_code_owner_review": false, + "require_last_push_approval": false, + "required_approving_review_count": 0, + "required_review_thread_resolution": false + } + } + ] +} diff --git a/.github/configs/rulesets-gh-pages.json b/.github/configs/rulesets-gh-pages.json new file mode 100644 index 00000000..ebf38928 --- /dev/null +++ b/.github/configs/rulesets-gh-pages.json @@ -0,0 +1,19 @@ +{ + "name": "gh-pages branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["refs/heads/gh-pages"], + "exclude": [] + } + }, + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + } + ] +} diff --git a/.github/configs/rulesets-master.json b/.github/configs/rulesets-master.json new file mode 100644 index 00000000..f658a5c6 --- /dev/null +++ b/.github/configs/rulesets-master.json @@ -0,0 +1,30 @@ +{ + "name": "master branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["~DEFAULT_BRANCH"], + "exclude": [] + } + }, + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + }, + { + "type": "pull_request", + "parameters": { + "allowed_merge_methods": ["merge"], + "dismiss_stale_reviews_on_push": false, + "require_code_owner_review": false, + "require_last_push_approval": false, + "required_approving_review_count": 0, + "required_review_thread_resolution": false + } + } + ] +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 881b2c53..533cae79 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,32 +2,40 @@ ## Project Overview -EasyReflectometryLib is a reflectometry Python package built on the EasyScience framework. It provides tools for reflectometry analysis and modeling. +EasyReflectometryLib is a reflectometry Python package built on the +EasyScience framework. It provides tools for reflectometry analysis and +modeling. ## Development Environment - **Python Versions**: 3.11, 3.12 -- **Supported Platforms**: Linux (ubuntu-latest), macOS (macos-latest), Windows (windows-latest) +- **Supported Platforms**: Linux (ubuntu-latest), macOS (macos-latest), + Windows (windows-latest) - **Package Manager**: pip - **Build System**: hatchling with setuptools-git-versioning ## Code Style and Formatting ### Ruff Configuration -- Use **Ruff** for linting and formatting (configured in `pyproject.toml`) + +- Use **Ruff** for linting and formatting (configured in + `pyproject.toml`) - Maximum line length: 127 characters - Quote style: single quotes for strings - Import style: force single-line imports - To fix issues automatically: `python -m ruff . --fix` ### Code Quality Standards + - Follow PEP 8 guidelines - Use type hints where appropriate - Write clear, self-documenting code with meaningful variable names - Maintain consistency with existing code patterns in the repository ### Linting Rules + The project uses Ruff with the following rule sets: + - `E9`, `F63`, `F7`, `F82`: Critical flake8 rules - `E`: pycodestyle errors - `F`: Pyflakes @@ -35,6 +43,7 @@ The project uses Ruff with the following rule sets: - `S`: flake8-bandit (security checks) Special notes: + - Asserts are allowed in test files (`*test_*.py`) - Init module imports are ignored - Exclude `docs` directory from linting @@ -42,12 +51,14 @@ Special notes: ## Testing ### Test Framework + - Use **pytest** for all tests - Test coverage should be tracked with **pytest-cov** - Aim for comprehensive test coverage - Tests are located in the `tests/` directory ### Running Tests + ```bash # Install dev dependencies pip install -e '.[dev]' @@ -61,6 +72,7 @@ tox ``` ### Test Guidelines + - Write unit tests for all new functionality - Include tests when fixing bugs to prevent regression - Test files should match the pattern `test_*.py` @@ -77,11 +89,14 @@ tox ## Documentation ### Docstring Style + - Include docstrings for all public modules, classes, and functions -- Use **Sphinx/reStructuredText style** docstrings (`:param`, `:type`, `:return`, `:rtype`) +- Use **Sphinx/reStructuredText style** docstrings (`:param`, `:type`, + `:return`, `:rtype`) - Use clear, concise descriptions - Document parameters, return values, and exceptions - Example format: + ```python """ Brief description of the function. @@ -94,6 +109,7 @@ tox ``` ### Documentation Build + - Documentation is built using Sphinx (version 8.1.3) - Source files are in the `docs/` directory - Use `myst_parser` (MyST parser) for Markdown support @@ -102,6 +118,7 @@ tox ## Dependencies ### Core Dependencies + - easyscience (EasyScience framework) - scipp (Scientific computing) - refnx, refl1d (Reflectometry calculations) @@ -109,6 +126,7 @@ tox - bumps (Optimization) ### Adding New Dependencies + - Only add dependencies when absolutely necessary - Add to appropriate section in `pyproject.toml`: - `dependencies` for core runtime dependencies @@ -119,13 +137,16 @@ tox ## Git and Version Control ### Commit Messages + - Write clear, descriptive commit messages - Use present tense ("Add feature" not "Added feature") - Reference issue numbers when applicable ### Branch Workflow + - Create feature branches from the main branch -- Use descriptive branch names (e.g., `feature/add-new-calculator`, `bugfix/fix-reflection-calculation`) +- Use descriptive branch names (e.g., `feature/add-new-calculator`, + `bugfix/fix-reflection-calculation`) - Keep changes focused and atomic ## Pull Request Guidelines @@ -157,17 +178,24 @@ docs/ # Documentation source ## Best Practices -1. **Minimal Changes**: Make the smallest possible changes to accomplish the task -2. **Don't Break Existing Code**: Maintain backward compatibility unless explicitly required -3. **Test Before Committing**: Always run tests and linting before pushing -4. **Follow Existing Patterns**: Look at similar code in the repository for guidance -5. **Ask When Uncertain**: If unsure about an approach, ask for clarification +1. **Minimal Changes**: Make the smallest possible changes to accomplish + the task +2. **Don't Break Existing Code**: Maintain backward compatibility unless + explicitly required +3. **Test Before Committing**: Always run tests and linting before + pushing +4. **Follow Existing Patterns**: Look at similar code in the repository + for guidance +5. **Ask When Uncertain**: If unsure about an approach, ask for + clarification ## CI/CD Pipeline The project uses GitHub Actions for continuous integration: + - **Code Consistency**: Runs Ruff linting on all pushes and PRs -- **Code Testing**: Runs pytest across multiple Python versions and platforms +- **Code Testing**: Runs pytest across multiple Python versions and + platforms - **Package Testing**: Validates package building and installation - **Coverage**: Uploads test coverage to Codecov @@ -177,5 +205,6 @@ All CI checks must pass before merging PRs. - The project is part of the EasyScience ecosystem - Built on top of established reflectometry libraries (refnx, refl1d) -- Focuses on providing a user-friendly interface for reflectometry analysis +- Focuses on providing a user-friendly interface for reflectometry + analysis - Maintains compatibility with multiple calculator backends diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index cc95caf6..4f0d1964 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -4,30 +4,30 @@ name-template: v$NEXT_PATCH_VERSION 🌈 tag-template: v$NEXT_PATCH_VERSION categories: -- title: 🚀 Features - labels: - - feature - - enhancement -- title: 🐛 Bug Fixes - labels: - - fix - - bugfix - - bug -- title: 🧰 Maintenance - labels: - - chore - - documentation + - title: 🚀 Features + labels: + - feature + - enhancement + - title: 🐛 Bug Fixes + labels: + - fix + - bugfix + - bug + - title: 🧰 Maintenance + labels: + - chore + - documentation change-template: '- $TITLE @$AUTHOR (#$NUMBER)' version-resolver: major: labels: - - major + - major minor: labels: - - minor + - minor patch: labels: - - patch + - patch default: patch template: | ## Changes diff --git a/.github/scripts/backmerge-conflict-issue.js b/.github/scripts/backmerge-conflict-issue.js new file mode 100644 index 00000000..f6bd98b5 --- /dev/null +++ b/.github/scripts/backmerge-conflict-issue.js @@ -0,0 +1,69 @@ +module.exports = async ({ github, context, core }) => { + // Repo context + const owner = context.repo.owner + const repo = context.repo.repo + + // Link to the exact workflow run that detected the conflict + const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}` + + // We use a *stable title* so we can find/reuse the same "conflict tracker" issue + // instead of creating a new issue on every failed run. + const title = 'Backmerge conflict: master → develop' + + // Comment/issue body includes the run URL so maintainers can jump straight to logs. + const body = [ + 'Automatic backmerge failed due to merge conflicts.', + '', + `Workflow run: ${runUrl}`, + '', + 'Manual resolution required.', + ].join('\n') + + // Label applied to the tracker issue (assumed to already exist in the repo). + const label = '[bot] backmerge' + + // Search issues by title across *open and closed* issues. + // Why: if the conflict was resolved previously and the issue was closed, + // we prefer to reopen it and append a new comment instead of creating duplicates. + const q = `repo:${owner}/${repo} is:issue in:title "${title}"` + const search = await github.rest.search.issuesAndPullRequests({ + q, + per_page: 10, + }) + + // Pick the first exact-title match (search can return partial matches). + const existing = search.data.items.find((i) => i.title === title) + + if (existing) { + // If a tracker issue exists, reuse it: + // - reopen it if needed + // - add a comment with the new run URL + if (existing.state === 'closed') { + await github.rest.issues.update({ + owner, + repo, + issue_number: existing.number, + state: 'open', + }) + } + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: existing.number, + body, + }) + + core.notice(`Conflict issue updated: #${existing.number}`) + return + } + + // No tracker issue exists yet -> create the first one. + await github.rest.issues.create({ + owner, + repo, + title, + body, + labels: [label], + }) +} diff --git a/.github/scripts/publish-dashboard.sh b/.github/scripts/publish-dashboard.sh new file mode 100644 index 00000000..dcbd0b32 --- /dev/null +++ b/.github/scripts/publish-dashboard.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -euo pipefail + +remote_repository="${DASHBOARD_REMOTE_REPOSITORY:?}" +publish_branch="${DASHBOARD_PUBLISH_BRANCH:-master}" +source_dir="${DASHBOARD_SOURCE_DIR:?}" +token="${DASHBOARD_TOKEN:?}" +git_user_name="${DASHBOARD_GIT_USER_NAME:-easyscience[bot]}" +git_user_email="${DASHBOARD_GIT_USER_EMAIL:?}" +commit_message="${DASHBOARD_COMMIT_MESSAGE:?}" +max_attempts="${DASHBOARD_PUSH_ATTEMPTS:-3}" +delay_seconds="${DASHBOARD_PUSH_DELAY_SECONDS:-15}" + +workspace_dir="$(mktemp -d)" +repo_dir="${workspace_dir}/dashboard" +remote_url="https://x-access-token:${token}@github.com/${remote_repository}.git" + +cleanup() { + rm -rf "${workspace_dir}" +} + +prepare_worktree() { + if [[ ! -d "${repo_dir}/.git" ]]; then + git clone --branch "${publish_branch}" --depth 1 "${remote_url}" "${repo_dir}" + else + git -C "${repo_dir}" fetch origin "${publish_branch}" + git -C "${repo_dir}" checkout "${publish_branch}" + git -C "${repo_dir}" reset --hard "origin/${publish_branch}" + git -C "${repo_dir}" clean -fd + fi + + git -C "${repo_dir}" config user.name "${git_user_name}" + git -C "${repo_dir}" config user.email "${git_user_email}" +} + +sync_publish_dir() { + cp -R "${source_dir}/." "${repo_dir}/" + git -C "${repo_dir}" add . + + if git -C "${repo_dir}" diff --cached --quiet; then + return 1 + fi + + git -C "${repo_dir}" commit -m "${commit_message}" +} + +trap cleanup EXIT + +prepare_worktree + +if ! sync_publish_dir; then + echo "No dashboard changes to publish." + exit 0 +fi + +for ((attempt = 1; attempt <= max_attempts; attempt += 1)); do + if git -C "${repo_dir}" push origin "HEAD:${publish_branch}"; then + echo "Dashboard published on attempt ${attempt}." + exit 0 + fi + + if ((attempt == max_attempts)); then + echo "Dashboard publish failed after ${max_attempts} attempts." >&2 + exit 1 + fi + + echo "Dashboard push attempt ${attempt} failed. Retrying in ${delay_seconds}s." >&2 + sleep "${delay_seconds}" + + prepare_worktree + + if ! sync_publish_dir; then + echo "Dashboard changes already exist in the target repository." + exit 0 + fi +done \ No newline at end of file diff --git a/.github/workflows/backmerge.yml b/.github/workflows/backmerge.yml new file mode 100644 index 00000000..36ce6f54 --- /dev/null +++ b/.github/workflows/backmerge.yml @@ -0,0 +1,109 @@ +# This workflow automatically merges `master` into `develop` whenever a +# new version release with a tag is published. It can also be triggered +# manually via workflow_dispatch for cases where an automatic backmerge +# is needed outside of the standard release process. +# If a merge conflict occurs, the workflow creates an issue to notify +# maintainers for manual resolution. + +name: Backmerge (master → develop) + +on: + release: + types: [published, prereleased] + workflow_dispatch: + +permissions: + contents: write + issues: write + +concurrency: + group: backmerge-master-into-develop + cancel-in-progress: false + +jobs: + backmerge: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout repository (for local actions) + uses: actions/checkout@v6 + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + repositories: ${{ github.event.repository.name }} + + - name: Checkout repository (with bot token) + uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ steps.bot.outputs.token }} + + - name: Configure git identity + run: | + git config user.name "easyscience[bot]" + git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com" + + - name: Set merge message + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + MESSAGE="Backmerge: master into develop (manual) [skip ci]" + else + TAG="${{ github.event.release.tag_name }}" + MESSAGE="Backmerge: master (${TAG}) into develop [skip ci]" + fi + + echo "MESSAGE=$MESSAGE" >> "$GITHUB_ENV" + echo "message=$MESSAGE" >> "$GITHUB_OUTPUT" + echo "📝 Merge message: $MESSAGE" | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Prepare branches + run: | + git fetch origin master develop + git checkout -B develop origin/develop + + - name: Check if develop is already up-to-date + id: up_to_date + run: | + if git merge-base --is-ancestor origin/master develop; then + echo "value=true" >> "$GITHUB_OUTPUT" + echo "ℹ️ Develop is already up-to-date with master" | tee -a "$GITHUB_STEP_SUMMARY" + else + echo "value=false" >> "$GITHUB_OUTPUT" + fi + + - name: Try merge master into develop + id: merge + if: steps.up_to_date.outputs.value == 'false' + continue-on-error: true + run: | + if ! git merge origin/master --no-ff -m "${MESSAGE}"; then + echo "conflict=true" >> "$GITHUB_OUTPUT" + echo "❌ Backmerge conflict detected." | tee -a "$GITHUB_STEP_SUMMARY" + git status --porcelain || true + exit 0 + fi + + echo "conflict=false" >> "$GITHUB_OUTPUT" + echo "✅ Merge commit created." | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Push to develop (if merge succeeded) + if: + steps.up_to_date.outputs.value == 'false' && steps.merge.outputs.conflict == + 'false' + run: | + git push origin develop + echo "🚀 Backmerge successful: master → develop" | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Create issue (if merge failed with conflicts) + if: steps.merge.outputs.conflict == 'true' + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + const run = require('./.github/scripts/backmerge-conflict-issue.js') + await run({ github, context, core }) diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml new file mode 100644 index 00000000..21c72b38 --- /dev/null +++ b/.github/workflows/cleanup.yml @@ -0,0 +1,84 @@ +# This workflow will delete old workflow runs based on the input +# parameters. +# https://github.com/Mattraks/delete-workflow-runs + +name: Old workflow runs cleanup + +on: + # Run monthly, at 00:00 on the 1st day of month. + schedule: + - cron: '0 0 1 * *' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + inputs: + days: + description: 'Number of days.' + required: true + default: '30' + minimum_runs: + description: 'The minimum runs to keep for each workflow.' + required: true + default: '6' + delete_workflow_pattern: + description: + 'The name or filename of the workflow. if not set then it will target all + workflows.' + required: false + delete_workflow_by_state_pattern: + description: + 'Remove workflow by state: active, deleted, disabled_fork, + disabled_inactivity, disabled_manually' + required: true + default: 'All' + type: choice + options: + - 'All' + - active + - deleted + - disabled_inactivity + - disabled_manually + delete_run_by_conclusion_pattern: + description: + 'Remove workflow by conclusion: action_required, cancelled, failure, skipped, + success' + required: true + default: 'All' + type: choice + options: + - 'All' + - action_required + - cancelled + - failure + - skipped + - success + dry_run: + description: 'Only log actions, do not perform any delete operations (dry run).' + required: false + default: 'false' + type: choice + options: + - 'false' + - 'true' + +jobs: + del-runs: + runs-on: ubuntu-latest + + permissions: + actions: write + + steps: + - name: Delete workflow runs + uses: Mattraks/delete-workflow-runs@v2 + with: + token: ${{ github.token }} + repository: ${{ github.repository }} + retain_days: ${{ github.event.inputs.days }} + keep_minimum_runs: ${{ github.event.inputs.minimum_runs }} + delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }} + delete_workflow_by_state_pattern: + ${{ github.event.inputs.delete_workflow_by_state_pattern }} + delete_run_by_conclusion_pattern: + ${{ github.event.inputs.delete_run_by_conclusion_pattern }} + dry_run: ${{ github.event.inputs.dry_run }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b388f884..238dc354 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,11 +1,11 @@ -name: "CodeQL" +name: 'CodeQL' on: push: - branches: [ master, pre-release, develop ] + branches: [master, pre-release, develop] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [master] schedule: - cron: '0 16 * * 5' @@ -24,43 +24,43 @@ jobs: # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 + - name: Checkout repository + uses: actions/checkout@v4 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@master + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@master - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 \ No newline at end of file + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..d96e5b87 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,94 @@ +name: Coverage checks + +on: + # Trigger the workflow on push to develop + push: + branches: + - develop + # Trigger the workflow on pull request + pull_request: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Need permissions to trigger the dashboard build workflow +permissions: + actions: write + contents: read + +# Allow only one concurrent workflow per PR or branch ref. +# Cancel in-progress runs only for pull requests, but let branch push runs finish. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + # Job 1: Run docstring coverage + docstring-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run docstring coverage + run: pixi run docstring-coverage + + # Job 2: Run unit tests with coverage and upload to Codecov + unit-tests-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run unit tests with coverage + run: pixi run unit-tests-coverage --cov-report=xml:coverage-unit.xml + + - name: Upload unit tests coverage to Codecov + if: ${{ !cancelled() }} + uses: ./.github/actions/upload-codecov + with: + name: unit-tests-job + flags: unittests + files: ./coverage-unit.xml + token: ${{ secrets.CODECOV_TOKEN }} + + # Job 2: Run integration tests with coverage and upload to Codecov + integration-tests-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run integration tests with coverage + run: + pixi run integration-tests-coverage --cov-report=xml:coverage-integration.xml + + - name: Upload integration tests coverage to Codecov + if: ${{ !cancelled() }} + uses: ./.github/actions/upload-codecov + with: + name: integration-tests-job + flags: integration + files: ./coverage-integration.xml + token: ${{ secrets.CODECOV_TOKEN }} + + # Job 4: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: [docstring-coverage, unit-tests-coverage, integration-tests-coverage] # depend on the previous jobs + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/dashboard.yml b/.github/workflows/dashboard.yml new file mode 100644 index 00000000..9d1f2b0b --- /dev/null +++ b/.github/workflows/dashboard.yml @@ -0,0 +1,111 @@ +name: Dashboard build and publish + +on: + workflow_dispatch: + workflow_call: + +permissions: + contents: read + +concurrency: + group: dashboard-publish-${{ github.repository }} + cancel-in-progress: false + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + DEVELOP_BRANCH: develop + REPO_OWNER: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + +jobs: + dashboard: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Install badgery + shell: bash + run: pixi add --pypi --git https://github.com/enhantica/badgery badgery + + - name: Run docstring coverage and code complexity/maintainability checks + run: | + for BRANCH in $DEFAULT_BRANCH $DEVELOP_BRANCH $CI_BRANCH; do + echo + echo "🔹🔸🔹🔸🔹 Processing branch $BRANCH 🔹🔸🔹🔸🔹" + if [ -d "../$BRANCH" ]; then + echo "Branch $BRANCH already processed, skipping" + continue + fi + + git worktree add ../$BRANCH origin/$BRANCH + mkdir -p reports/$BRANCH + + echo "Docstring coverage for branch $BRANCH" + pixi run interrogate -c pyproject.toml --fail-under=0 ../$BRANCH/src > reports/$BRANCH/coverage-docstring.txt + + echo "Cyclomatic complexity for branch $BRANCH" + pixi run radon cc -s -j ../$BRANCH/src > reports/$BRANCH/cyclomatic-complexity.json + + echo "Maintainability index for branch $BRANCH" + pixi run radon mi -j ../$BRANCH/src > reports/$BRANCH/maintainability-index.json + + echo "Raw metrics for branch $BRANCH" + pixi run radon raw -s -j ../$BRANCH/src > reports/$BRANCH/raw-metrics.json + done + + - name: Generate dashboard HTML + run: > + pixi run python -m badgery --config .badgery.yaml --repo ${{ github.repository + }} --branch ${{ env.CI_BRANCH }} --output index.html + + - name: Prepare publish directory + run: | + mkdir -p _dashboard_publish/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }} + cp index.html _dashboard_publish/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }} + + # Create GitHub App token for pushing to external dashboard repo. + # The 'repositories' parameter is required to grant access to repos + # other than the one where the workflow is running. + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + repositories: | + ${{ github.event.repository.name }} + dashboard + + # Push to external dashboard repository with retry logic. + # Retry is needed to handle transient GitHub API/authentication issues + # that occasionally cause 403 errors when multiple workflows push concurrently. + # Uses personal_token (not github_token) as GITHUB_TOKEN cannot access external repos. + - name: + Push to ${{ env.REPO_OWNER }}/dashboard/${{ env.REPO_NAME }}/${{ env.CI_BRANCH + }} + shell: bash + env: + DASHBOARD_COMMIT_MESSAGE: ${{ env.CI_BRANCH }} + DASHBOARD_GIT_USER_EMAIL: + ${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com + DASHBOARD_PUSH_ATTEMPTS: '3' + DASHBOARD_PUSH_DELAY_SECONDS: '15' + DASHBOARD_PUBLISH_BRANCH: master + DASHBOARD_REMOTE_REPOSITORY: ${{ env.REPO_OWNER }}/dashboard + DASHBOARD_SOURCE_DIR: ./_dashboard_publish + DASHBOARD_TOKEN: ${{ steps.bot.outputs.token }} + run: bash ./.github/scripts/publish-dashboard.sh + + - name: Add dashboard link to summary + run: | + URL="https://${{ env.REPO_OWNER }}.github.io/dashboard/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }}" + echo "Dashboard link: [$URL]($URL)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..d8622c29 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,188 @@ +# This workflow builds and deploys documentation for the project. +# +# Overview: +# - Converts tutorial Python scripts to Jupyter notebooks and executes them. +# - Builds the documentation site using MkDocs with the Material theme. +# - Uploads the built site as an artifact for local inspection. +# - Deploys versioned documentation to the gh-pages branch using Mike: +# - For release tags (v*): deploys to a versioned folder (e.g., /0.9.1/) and updates /latest/. +# - For branches: deploys to /dev/. +# +# The action summary page will contain a link to the built artifact for downloading +# and inspecting, as well as a link to the deployed documentation site. + +name: Docs build and deployment + +on: + # Trigger the workflow on push + push: + # Selected branches + branches: [develop] # master and main are already verified in PR + # Runs on creating a new tag starting with 'v', e.g. 'v1.0.3' + tags: ['v*'] + # Trigger the workflow on pull request + pull_request: + # Selected branches + branches: [master, main, develop] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# - Non-tagged pushes and pull requests all use `docs-dev` group, so +# they cancel each other. +# - Tagged pushes use their own group like docs-v1.2.3, so they do not +# cancel non-tagged runs, and non-tagged runs do not cancel them. +concurrency: + group: >- + ${{ startsWith(github.ref, 'refs/tags/v') + && format('docs-{0}', github.ref_name) + || 'docs-dev' }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + # CI_BRANCH - the branch name (used in mkdocs.yml) + # For PRs: github.head_ref is the source branch + # For pushes: github.ref_name is the branch + # For tags: github.ref_name is the tag name + # GITHUB_REPOSITORY - the repository name (used in mkdocs.yml) + # NOTEBOOKS_DIR - the directory containing the Jupyter notebooks (used in mkdocs.yml) + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + DEVELOP_BRANCH: develop + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + IS_RELEASE_TAG: ${{ startsWith(github.ref, 'refs/tags/v') }} + GITHUB_REPOSITORY: ${{ github.repository }} + NOTEBOOKS_DIR: tutorials + +jobs: + # Single job that builds and deploys documentation. + # Uses macOS runner for consistent Plotly chart rendering. + build-deploy-docs: + runs-on: ubuntu-latest # macos-latest + + permissions: + contents: write # Required for pushing to the gh-pages branch + + steps: + # Setting DOCS_VERSION to be used in mkdocs.yml, and then in the + # main.html template. It defines the versioned docs subfolder name + # in the gh-pages branch. If it's a release tag, use the version + # number without the 'v' prefix, otherwise use 'dev'. + # Setting RELEASE_VERSION to be used in mkdocs.yml to show + # the latest release version in the index.md file. If it's a + # release tag, use the tag name, otherwise use the branch name + # for development builds. + - name: Set extra env variables + shell: bash + run: | + if [[ "${IS_RELEASE_TAG}" == "true" ]]; then + RELEASE_VERSION="${GITHUB_REF_NAME}" + DOCS_VERSION="${RELEASE_VERSION#v}" + else + RELEASE_VERSION="${CI_BRANCH}" + DOCS_VERSION="dev" + fi + echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_ENV" + echo "DOCS_VERSION=${DOCS_VERSION}" >> "$GITHUB_ENV" + + # Check out the repository source code. + # Note: The gh-pages branch is fetched separately later for mike deployment. + - name: Checkout repository + uses: actions/checkout@v6 + + # Activate dark mode to create documentation with Plotly charts in dark mode + # Need a better solution to automatically switch the chart colour theme based on the mkdocs material switcher + # Something similar to mkdocs_plotly_plugin https://haoda-li.github.io/mkdocs-plotly-plugin/, + # but for generating documentation from notepads + #- name: Activate dark mode + # run: | + # brew install dark-mode + # dark-mode status + # dark-mode on + # dark-mode status + + # Set up the pixi package manager and install dependencies from pixi.toml. + # Uses frozen lockfile to ensure reproducible builds. + - name: Set up pixi + uses: ./.github/actions/setup-pixi + # Pre-import the main package to exclude info messages from the docs + # E.g., Matplotlib may print messages to stdout/stderr when first + # imported. This step allows to avoid "Matplotlib is building the font + # cache" messages during notebook execution. + - name: Pre-build site step + run: pixi run python -c "import easyreflectometry" + + # Prepare the Jupyter notebooks for documentation (strip output, etc.). + - name: Prepare notebooks + run: pixi run notebook-prepare + + # Execute all Jupyter notebooks to generate output cells (plots, tables, etc.). + # Uses multiple cores for parallel execution to speed up the process. + - name: Run notebooks + # if: false # Temporarily disabled to speed up the docs build + run: pixi run notebook-exec + + # Build the static files for the documentation site for local inspection + # Input: docs/ directory containing the Markdown files + # Output: site/ directory containing the generated HTML files + - name: Build site for local check + run: pixi run docs-build-local + + # Upload the static files from the site/ directory to be used for + # local check + - name: Upload built site as artifact + uses: ./.github/actions/upload-artifact + with: + name: site-local_easyreflectometry-lib-${{ env.RELEASE_VERSION }} + path: docs/site/ + + # Create GitHub App token for pushing to gh-pages as easyscience[bot]. + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + # Configure git identity and remote URL so mike pushes as easyscience[bot]. + - name: Configure git for pushing + run: | + set -euo pipefail + git config user.name "easyscience[bot]" + git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com" + git remote set-url origin "https://x-access-token:${{ steps.bot.outputs.token }}@github.com/${{ github.repository }}.git" + + # Fetch the gh-pages branch to ensure mike has the latest remote state. + # This is required because the checkout step only fetches the source branch, + # not the gh-pages branch that mike needs to update. + - name: Fetch gh-pages branch + run: | + git fetch origin gh-pages:gh-pages 2>/dev/null || true + + # Deploy versioned documentation using mike (MkDocs plugin for versioning). + # - For release tags (v*): deploys to versioned folder (e.g., /0.9.1/) and aliases to /latest/. + # - For branches: deploys to /dev/. + # The "${RELEASE_VERSION#v}" syntax strips the 'v' prefix (v0.9.1 -> 0.9.1). + # Also sets 'latest' as the default version for the version selector. + - name: Rebuild and deploy docs with mike + run: | + # Exit on error (-e), undefined vars (-u), and pipeline failures (pipefail) + set -euo pipefail + + REPO_NAME="${{ github.event.repository.name }}" + BASE_URL="https://easyscience.github.io/${REPO_NAME}" + + # Deploy the release version and update the "latest" alias + if [[ "${IS_RELEASE_TAG}" == "true" ]]; then + pixi run docs-deploy-pre "${RELEASE_VERSION#v}" latest + pixi run docs-set-default-pre latest + DEPLOYMENT_URL="${BASE_URL}/latest" + + # Deploy/update the "dev" alias (or whatever your convention is) + else + pixi run docs-deploy-pre dev + DEPLOYMENT_URL="${BASE_URL}/dev" + + fi + + # Add links to the action summary page for easy access + echo "🔗 deployment url [${DEPLOYMENT_URL}](${DEPLOYMENT_URL})" >> "${GITHUB_STEP_SUMMARY}" diff --git a/.github/workflows/documentation-build.yml b/.github/workflows/documentation-build.yml index f447b491..b3477bb6 100644 --- a/.github/workflows/documentation-build.yml +++ b/.github/workflows/documentation-build.yml @@ -29,40 +29,40 @@ jobs: # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: - contents: read # to clone the repository - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source + contents: read # to clone the repository + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source steps: - - name: Checkout - uses: actions/checkout@master - with: - fetch-depth: 0 # otherwise, you will failed to push refs to dest repo - - name: Upgrade pip - run: | - python -m pip install --upgrade pip - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.12 - - name: Install Pandoc, repo and dependencies - run: | - sudo apt install pandoc - sudo apt install libcairo2-dev - pip install sphinx==8.1.3 - pip install . '.[dev,docs]' + - name: Checkout + uses: actions/checkout@master + with: + fetch-depth: 0 # otherwise, you will failed to push refs to dest repo + - name: Upgrade pip + run: | + python -m pip install --upgrade pip + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Install Pandoc, repo and dependencies + run: | + sudo apt install pandoc + sudo apt install libcairo2-dev + pip install sphinx==8.1.3 + pip install . '.[dev,docs]' - - name: Install Jupyter kernel - run: | - python -m ipykernel install --user --name=python3 + - name: Install Jupyter kernel + run: | + python -m ipykernel install --user --name=python3 - - name: Build and Commit - uses: sphinx-notes/pages@v3 - with: - sphinx_version: 8.1.3 - documentation_path: docs/src - - name: Push changes - uses: ad-m/github-push-action@master - continue-on-error: true - with: - branch: gh-pages \ No newline at end of file + - name: Build and Commit + uses: sphinx-notes/pages@v3 + with: + sphinx_version: 8.1.3 + documentation_path: docs/src + - name: Push changes + uses: ad-m/github-push-action@master + continue-on-error: true + with: + branch: gh-pages diff --git a/.github/workflows/issues-labels.yml b/.github/workflows/issues-labels.yml new file mode 100644 index 00000000..56ab5b19 --- /dev/null +++ b/.github/workflows/issues-labels.yml @@ -0,0 +1,149 @@ +# Verifies if the current issue has at least one real `[scope]` label and one +# real `[priority]` label. If either is missing, the workflow adds a reminder +# label with a warning emoji. + +name: Issue labels check + +on: + issues: + types: [opened, labeled, unlabeled] + +permissions: + issues: write + +jobs: + check-labels: + runs-on: ubuntu-latest + + concurrency: + group: issue-labels-${{ github.event.issue.number }} + cancel-in-progress: true + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Sync missing-label reminders + uses: ./.github/actions/github-script + with: + script: | + const fs = require('fs'); + + const issueNumber = context.issue.number; + const action = context.payload.action; + const changedLabel = context.payload.label?.name ?? null; + const labels = context.payload.issue.labels.map(({ name }) => name); + const requirements = [ + { + prefix: '[scope] ', + reminder: '[scope] ⚠️ label needed', + }, + { + prefix: '[priority] ', + reminder: '[priority] ⚠️ label needed', + }, + ]; + + const labelsToAdd = []; + const labelsToRemove = []; + const evaluations = []; + + console.log(`::group::Issue label check for #${issueNumber}`); + console.log(`Event action: ${action}`); + if (changedLabel) { + console.log(`Event label: ${changedLabel}`); + } + console.log( + `Current labels: ${labels.length > 0 ? labels.join(', ') : '(none)'}`, + ); + + for (const { prefix, reminder } of requirements) { + const matchingRealLabels = labels.filter( + (name) => name.startsWith(prefix) && name !== reminder, + ); + const hasRealLabel = matchingRealLabels.length > 0; + const hasReminderLabel = labels.includes(reminder); + + evaluations.push({ + prefix, + reminder, + matchingRealLabels, + hasReminderLabel, + }); + + if (hasRealLabel && hasReminderLabel) { + labelsToRemove.push(reminder); + } else if (!hasRealLabel && !hasReminderLabel) { + labelsToAdd.push(reminder); + } + } + + for (const evaluation of evaluations) { + if (evaluation.matchingRealLabels.length > 0) { + console.log( + `Found required ${evaluation.prefix}label(s): ${evaluation.matchingRealLabels.join(', ')}`, + ); + } else { + console.log(`Missing required ${evaluation.prefix}label.`); + } + + if (evaluation.hasReminderLabel) { + console.log(`Reminder label already present: ${evaluation.reminder}`); + } + } + + if (labelsToAdd.length > 0) { + console.log(`Adding reminder labels: ${labelsToAdd.join(', ')}`); + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: labelsToAdd, + }); + } + + for (const name of labelsToRemove) { + console.log(`Removing reminder label: ${name}`); + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + name, + }); + } + + if (labelsToAdd.length === 0 && labelsToRemove.length === 0) { + console.log('No label changes required.'); + } + + console.log('::endgroup::'); + + if (process.env.GITHUB_STEP_SUMMARY) { + const summaryLines = [ + '### Issue Label Check', + `- Issue: #${issueNumber}`, + `- Event: ${action}`, + `- Trigger label: ${changedLabel ?? '(none)'}`, + `- Current labels: ${labels.length > 0 ? labels.join(', ') : '(none)'}`, + '', + '#### Requirement status', + ...evaluations.map((evaluation) => { + const status = + evaluation.matchingRealLabels.length > 0 + ? `found ${evaluation.matchingRealLabels.join(', ')}` + : 'missing'; + const reminder = evaluation.hasReminderLabel + ? `reminder present: ${evaluation.reminder}` + : `reminder absent: ${evaluation.reminder}`; + return `- ${evaluation.prefix}: ${status}; ${reminder}`; + }), + '', + `- Labels to add: ${labelsToAdd.length > 0 ? labelsToAdd.join(', ') : '(none)'}`, + `- Labels to remove: ${labelsToRemove.length > 0 ? labelsToRemove.join(', ') : '(none)'}`, + ]; + + fs.appendFileSync( + process.env.GITHUB_STEP_SUMMARY, + `${summaryLines.join('\n')}\n`, + ); + } diff --git a/.github/workflows/lint-format.yml b/.github/workflows/lint-format.yml new file mode 100644 index 00000000..16dd95c9 --- /dev/null +++ b/.github/workflows/lint-format.yml @@ -0,0 +1,124 @@ +# The workflow checks +# - the validity of pyproject.toml, +# - the presence and correctness of SPDX license headers, +# - linting and formatting of Python code, +# - linting and formatting of docstrings in Python code, +# - formatting of non-Python files (like markdown and toml). +# - linting of Python code in Jupyter notebooks (for library template). +# +# A summary of the checks is added to the GitHub Actions summary. + +name: Lint and format checks + +on: + # Trigger the workflow on push + push: + branches-ignore: [master, main] # Already verified in PR + # Do not run this workflow on creating a new tag starting with + # 'v', e.g. 'v1.0.3' (see publish-pypi.yml) + tags-ignore: ['v*'] + # Trigger the workflow on pull request + pull_request: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + lint-format: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run post-install developer steps + run: pixi run post-install + + - name: Check validity of pyproject.toml + id: pyproject + continue-on-error: true + shell: bash + run: pixi run pyproject-check + + - name: Check SPDX license headers + id: license_headers + continue-on-error: true + shell: bash + run: pixi run license-check + + - name: Check linting of Python code + id: py_lint + continue-on-error: true + shell: bash + run: pixi run py-lint-check + + - name: Check formatting of Python code + id: py_format + continue-on-error: true + shell: bash + run: pixi run py-format-check + + - name: Check linting of docstrings in Python code + id: docstring_lint + continue-on-error: true + shell: bash + run: pixi run docstring-lint-check + + - name: Check formatting of non-Python files (md, toml, etc.) + id: nonpy_format + continue-on-error: true + shell: bash + run: pixi run nonpy-format-check + + - name: Check linting of Python code in Jupyter notebooks (ipynb) + id: notebook_lint + continue-on-error: true + shell: bash + run: pixi run notebook-lint-check + + # Add summary + - name: Add quality checks summary + if: always() + shell: bash + run: | + { + echo "## 🧪 Checks Summary" + echo "" + echo "| Check | Status |" + echo "|-------|--------|" + echo "| pyproject.toml | ${{ steps.pyproject.outcome == 'success' && '✅' || '❌' }} |" + echo "| license headers | ${{ steps.license_headers.outcome == 'success' && '✅' || '❌' }} |" + echo "| py lint | ${{ steps.py_lint.outcome == 'success' && '✅' || '❌' }} |" + echo "| py format | ${{ steps.py_format.outcome == 'success' && '✅' || '❌' }} |" + echo "| docstring lint | ${{ steps.docstring_lint.outcome == 'success' && '✅' || '❌' }} |" + echo "| nonpy format | ${{ steps.nonpy_format.outcome == 'success' && '✅' || '❌' }} |" + echo "| notebooks lint | ${{ steps.notebook_lint.outcome == 'success' && '✅' || '❌' }} |" + } >> "$GITHUB_STEP_SUMMARY" + + # Fail job if any check failed + - name: Fail job if any check failed + if: | + steps.pyproject.outcome == 'failure' + || steps.license_headers.outcome == 'failure' + || steps.py_lint.outcome == 'failure' + || steps.py_format.outcome == 'failure' + || steps.docstring_lint.outcome == 'failure' + || steps.nonpy_format.outcome == 'failure' + || steps.notebook_lint.outcome == 'failure' + shell: bash + run: exit 1 diff --git a/.github/workflows/ossar-analysis.yml b/.github/workflows/ossar-analysis.yml index a2c77306..94859565 100644 --- a/.github/workflows/ossar-analysis.yml +++ b/.github/workflows/ossar-analysis.yml @@ -3,7 +3,6 @@ # # For more information see: https://github.com/github/ossar-action - name: OSSAR on: @@ -17,35 +16,34 @@ jobs: steps: # Checkout your code repository to scan - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Ensure a compatible version of dotnet is installed. - # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. - # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. - # Remote agents already have a compatible version of dotnet installed and this step may be skipped. - # For local agents, ensure dotnet version 3.1.201 or later is installed by including this action: - # - name: Install .NET - # uses: actions/setup-dotnet@v1 - # with: - # dotnet-version: '3.1.x' - + - name: Checkout repository + uses: actions/checkout@v4 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Ensure a compatible version of dotnet is installed. + # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. + # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. + # Remote agents already have a compatible version of dotnet installed and this step may be skipped. + # For local agents, ensure dotnet version 3.1.201 or later is installed by including this action: + # - name: Install .NET + # uses: actions/setup-dotnet@v1 + # with: + # dotnet-version: '3.1.x' # Run open source static analysis tools - - name: Run OSSAR - uses: github/ossar-action@v2.0.0 - id: ossar - - # Upload results to the Security tab - - name: Upload OSSAR results - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} \ No newline at end of file + - name: Run OSSAR + uses: github/ossar-action@v2.0.0 + id: ossar + + # Upload results to the Security tab + - name: Upload OSSAR results + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: ${{ steps.ossar.outputs.sarifFile }} diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml new file mode 100644 index 00000000..25710633 --- /dev/null +++ b/.github/workflows/pr-labels.yml @@ -0,0 +1,63 @@ +# Verifies if a pull request has at least one label from a set of valid +# labels before it can be merged. +# +# NOTE: +# This workflow may be triggered twice in quick succession when a PR is +# created: +# 1) `opened` — when the pull request is initially created +# 2) `labeled` — if labels are added immediately after creation +# (e.g. by manual labeling, another workflow, or GitHub App). +# +# These are separate GitHub events, so two workflow runs can be started. +# The `concurrency` configuration below ensures that only the latest run +# for the same PR remains active, canceling any previous in-progress +# run. + +name: PR labels check + +on: + pull_request_target: + types: [opened, labeled, unlabeled, synchronize] + +concurrency: + group: pr-labels-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + pull-requests: read + +jobs: + check-labels: + runs-on: ubuntu-latest + + steps: + - name: Check for valid labels + run: | + PR_LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r '.[]') + + echo "Current PR labels: $PR_LABELS" + VALID_LABELS=( + "[bot] release" + "[scope] bug" + "[scope] documentation" + "[scope] enhancement" + "[scope] maintenance" + "[scope] significant" + ) + + found=false + for label in "${VALID_LABELS[@]}"; do + if echo "$PR_LABELS" | grep -Fxq "$label"; then + echo "✅ Found valid label: $label" + found=true + break + fi + done + + if [ "$found" = false ]; then + echo "ERROR: PR must have at least one of the following labels:" + for label in "${VALID_LABELS[@]}"; do + echo " - $label" + done + exit 1 + fi diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml new file mode 100644 index 00000000..0b431717 --- /dev/null +++ b/.github/workflows/pypi-publish.yml @@ -0,0 +1,46 @@ +# Builds a Python package and publish it to PyPI when a new tag is +# created. + +name: PyPI publishing + +on: + # Runs on creating a new tag starting with 'v', e.g. 'v1.0.3' + push: + tags: ['v*'] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + pypi-publish: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + + steps: + - name: Check-out repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 # full history with tags to get the version number by versioningit + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + # Build the Python package (to dist/ folder) + - name: Create Python package + run: pixi run default-build + + # Publish the package to PyPI (from dist/ folder) + # Instead of publishing with personal access token, we use + # GitHub Actions OIDC to get a short-lived token from PyPI. + # New publisher must be previously configured in PyPI at + # https://pypi.org/manage/project/easyreflectometry/settings/publishing/ + # Use the following data: + # Owner: easyscience + # Repository name: reflectometry-lib + # Workflow name: pypi-publish.yml + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: 'dist' diff --git a/.github/workflows/pypi-test.yml b/.github/workflows/pypi-test.yml new file mode 100644 index 00000000..2f4f58ac --- /dev/null +++ b/.github/workflows/pypi-test.yml @@ -0,0 +1,80 @@ +name: PyPI package tests + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + +jobs: + # Job 1: Test installation from PyPI on multiple OS + pypi-package-tests: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: '' + activate-environment: '' + run-install: false + frozen: false + + - name: Init pixi project + run: pixi init easyreflectometry + + - name: Set the minimum system requirements + working-directory: easyreflectometry + run: pixi project system-requirements add macos 14.0 + + - name: Add Python 3.13 from Conda + working-directory: easyreflectometry + run: pixi add "python=3.13" + + - name: Add other Conda dependencies + working-directory: easyreflectometry + run: pixi add gsl + + - name: Add easyreflectometry (with dev dependencies) from PyPI + working-directory: easyreflectometry + run: pixi add --pypi "easyreflectometry[dev]" + + - name: Run unit tests to verify the installation + working-directory: easyreflectometry + run: pixi run python -m pytest ../tests/unit/ --color=yes -v + + - name: Run functional tests to verify the installation + working-directory: easyreflectometry + run: pixi run python -m pytest ../tests/functional/ --color=yes -v + + - name: Run integration tests to verify the installation + working-directory: easyreflectometry + run: pixi run python -m pytest ../tests/integration/ --color=yes -n auto + + # Job 2: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: pypi-package-tests # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 1d33313f..ea40ee70 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -1,4 +1,4 @@ -# This workflow will for a variety of Python versions +# This workflow will for a variety of Python versions # - install the code base # - lint the code base # - test the code base @@ -21,8 +21,8 @@ jobs: - name: Suggestion to fix issues if: ${{ failure() }} run: | - echo "::notice::In project root run 'python.exe -m ruff . --fix' and commit changes to fix issues." - exit 1 + echo "::notice::In project root run 'python.exe -m ruff . --fix' and commit changes to fix issues." + exit 1 Code_Testing: strategy: @@ -35,56 +35,54 @@ jobs: if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Upgrade pip - run: | - python -m pip install --upgrade pip + - uses: actions/checkout@v4 - - name: Install dependencies - run: pip install -e '.[dev]' + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} - - name: Test with pytest and coverage - run: | - pip install pytest pytest-cov - pytest --cov=src/easyreflectometry tests --cov-branch --cov-report=xml:coverage-unit.xml + - name: Upgrade pip + run: | + python -m pip install --upgrade pip - - name: Upload coverage reports to Codecov - # only on ubuntu to avoid multiple uploads - if: runner.os == 'Linux' - uses: codecov/codecov-action@v5 - with: - name: unit-tests-job - flags: unittests - files: ./coverage-unit.xml - fail_ci_if_error: false - verbose: true - token: ${{ secrets.CODECOV_TOKEN }} - slug: EasyScience/EasyReflectometryLib + - name: Install dependencies + run: pip install -e '.[dev]' + - name: Test with pytest and coverage + run: | + pip install pytest pytest-cov + pytest --cov=src/easyreflectometry tests --cov-branch --cov-report=xml:coverage-unit.xml + + - name: Upload coverage reports to Codecov + # only on ubuntu to avoid multiple uploads + if: runner.os == 'Linux' + uses: codecov/codecov-action@v5 + with: + name: unit-tests-job + flags: unittests + files: ./coverage-unit.xml + fail_ci_if_error: false + verbose: true + token: ${{ secrets.CODECOV_TOKEN }} + slug: EasyScience/EasyReflectometryLib Package_Testing: - runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: 3.11 + - uses: actions/setup-python@v5 + with: + python-version: 3.11 - - name: Install dependencies and build - run: | - pip install -e '.[dev]' - python -m build + - name: Install dependencies and build + run: | + pip install -e '.[dev]' + python -m build - - name: Check Build - run: | - cd ./dist - pytest ../ + - name: Check Build + run: | + cd ./dist + pytest ../ diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 3a4d1036..c0717847 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -9,34 +9,34 @@ name: Create Python Package on: push: - branches: [ master, pre-release ] + branches: [master, pre-release] pull_request: - branches: [ master, pre-release ] + branches: [master, pre-release] jobs: build: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.11','3.12','3.13'] + python-version: ['3.11', '3.12', '3.13'] if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies and build - run: | - pip install -e '.[dev]' - python -m build - - name: Test with pytest - run: | - cd ./dist - pytest ../ - - uses: actions/upload-artifact@v4 - with: - name: EasyReflectometrys - Python ${{ matrix.python-version }} - path: ${{ github.workspace }}/dist/* - overwrite: true \ No newline at end of file + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies and build + run: | + pip install -e '.[dev]' + python -m build + - name: Test with pytest + run: | + cd ./dist + pytest ../ + - uses: actions/upload-artifact@v4 + with: + name: EasyReflectometrys - Python ${{ matrix.python-version }} + path: ${{ github.workspace }}/dist/* + overwrite: true diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index dce167b2..38133fd1 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -4,7 +4,6 @@ # # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - name: Publish Python Package # Controls when the workflow will run @@ -19,24 +18,23 @@ on: jobs: deploy: - runs-on: ubuntu-latest permissions: id-token: write - + steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: 3.12 + - uses: actions/setup-python@v5 + with: + python-version: 3.12 - - name: Install dependencies and build - run: | - pip install -e '.[dev]' - python -m build + - name: Install dependencies and build + run: | + pip install -e '.[dev]' + python -m build - - name: Publish distribution 📦 to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - #with: - # password: ${{ secrets.PYPI_PASSWORD }} + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + #with: + # password: ${{ secrets.PYPI_PASSWORD }} diff --git a/.github/workflows/release-drafter-verify-pr-labels.yml b/.github/workflows/release-drafter-verify-pr-labels.yml index b024955b..3a8dbb4b 100644 --- a/.github/workflows/release-drafter-verify-pr-labels.yml +++ b/.github/workflows/release-drafter-verify-pr-labels.yml @@ -5,7 +5,6 @@ # # For more information see: https://github.com/marketplace/actions/release-drafter - name: Verify PR labels on: pull_request_target: @@ -16,11 +15,12 @@ jobs: runs-on: ubuntu-latest name: Verify that the PR has a valid label steps: - - name: Verify PR label action - uses: jesusvasquez333/verify-pr-label-action@v1.4.0 - id: verify-pr-label - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - valid-labels: chore, fix, bugfix, bug, enhancement, feature, dependencies, documentation - pull-request-number: ${{ github.event.pull_request.number }} - disable-reviews: false + - name: Verify PR label action + uses: jesusvasquez333/verify-pr-label-action@v1.4.0 + id: verify-pr-label + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + valid-labels: + chore, fix, bugfix, bug, enhancement, feature, dependencies, documentation + pull-request-number: ${{ github.event.pull_request.number }} + disable-reviews: false diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 31308447..51cd0d22 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -4,7 +4,6 @@ # Uses the release-drafter.yml configuration file in the .github directory. # https://github.com/marketplace/actions/release-drafter - name: Release Drafter on: diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 00000000..b6d8205c --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,71 @@ +# Drafts your next Release notes as pull requests are merged into +# default branch + +name: Release draft update + +on: + # Runs on pushes targeting the default branch (updates the real draft release) + push: + branches: [master, main] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + draft-release-notes: + permissions: + # write permission is required to create a github release + contents: write + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 # full history with tags to get the version number + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Drafts the next release notes + id: draft + uses: enhantica/drafterino@v2 + with: + config: | + title: 'easyreflectometry $COMPUTED_VERSION' + tag: 'v$COMPUTED_VERSION' + note-template: '- $PR_TITLE (#$PR_NUMBER)' + + default-bump: post + + major-bump-labels: ['[scope] significant'] + minor-bump-labels: ['[scope] enhancement'] + patch-bump-labels: ['[scope] bug', '[scope] maintenance'] + post-bump-labels: ['[scope] documentation'] + + release-notes: + - title: 'Added' + labels: ['[scope] significant', '[scope] enhancement'] + - title: 'Fixed' + labels: ['[scope] bug'] + - title: 'Changed' + labels: ['[scope] maintenance', '[scope] documentation'] + env: + GITHUB_TOKEN: ${{ steps.bot.outputs.token }} + + - name: Create GitHub draft release + uses: softprops/action-gh-release@v3 + with: + draft: true + tag_name: ${{ steps.draft.outputs.tag_name }} + name: ${{ steps.draft.outputs.release_name }} + body: ${{ steps.draft.outputs.release_notes }} + env: + GITHUB_TOKEN: ${{ steps.bot.outputs.token }} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml new file mode 100644 index 00000000..3fa073b9 --- /dev/null +++ b/.github/workflows/release-pr.yml @@ -0,0 +1,55 @@ +# This workflow creates an automated release PR from a source branch into the default branch. +# +# Usage: +# - Triggered manually via workflow_dispatch. +# - Creates a PR titled "Release: merge into ". +# - Adds the label "[bot] release" so it is excluded from changelogs. +# - The PR body makes clear that this is automation only (no review needed). + +name: 'Release PR (develop → master)' + +on: + workflow_dispatch: + inputs: + source_branch: + description: 'Source branch to create PR from' + required: false + default: 'develop' + type: string + +permissions: + contents: read + pull-requests: write + +env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + SOURCE_BRANCH: ${{ inputs.source_branch || 'develop' }} + +jobs: + create-pull-request: + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ env.SOURCE_BRANCH }} branch + uses: actions/checkout@v6 + with: + ref: ${{ env.SOURCE_BRANCH }} + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Create PR from ${{ env.SOURCE_BRANCH }} to ${{ env.DEFAULT_BRANCH }} + env: + GH_TOKEN: ${{ steps.bot.outputs.token }} + run: | + gh pr create \ + --base ${{ env.DEFAULT_BRANCH }} \ + --head ${{ env.SOURCE_BRANCH }} \ + --title "🎉 Release: merge ${{ env.SOURCE_BRANCH }} into ${{ env.DEFAULT_BRANCH }}" \ + --label "[bot] release" \ + --body "This PR is created automatically to trigger the release pipeline. It merges the accumulated changes from \`${{ env.SOURCE_BRANCH }}\` into \`${{ env.DEFAULT_BRANCH }}\`. + + ⚠️ It is labeled \`[bot] release\` and is excluded from release notes and version bump logic." diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..0f43db35 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,93 @@ +# Code scanning (CodeQL) for vulnerabilities and insecure coding patterns. +# +# What this workflow does +# - Runs GitHub CodeQL analysis and uploads results to your repository's Security tab. +# - Triggers on PRs (so findings appear as PR checks) and on pushes to `develop`. +# - Runs on a weekly schedule. +# +# Where to find results on GitHub +# - Repository → Security → Code scanning alerts +# (You can filter by tool = CodeQL and by branch.) +# +# Where to configure on GitHub +# - Repository → Settings → Advanced Security +# Enable "GitHub Advanced Security" (if available) and configure CodeQL there. +# - Repository → Security → Code scanning alerts +# This page shows findings produced by this workflow. +# +# Notes about the scheduled run +# - Scheduled workflows are triggered from the repository's *default branch*. +# If your default branch is `master` but you want the scheduled scan to analyze +# `develop`, this workflow checks out `develop` explicitly for scheduled runs. +# +# References +# - CodeQL Action: https://github.com/github/codeql-action +# - Advanced setup docs: https://docs.github.com/en/code-security/code-scanning + +name: Security scans with CodeQL + +on: + # Run on pull requests so results show up as PR checks and code + # scanning alerts. + pull_request: + branches: [master, main, develop] + + # Run on pushes (e.g., after merging PRs). + push: + branches: [master, main, develop] + + # Run weekly. (Cron is in UTC.) + schedule: + - cron: '0 3 * * 1' + +permissions: + contents: read + security-events: write + +jobs: + codeql: + name: Code scanning + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Keep this list tight to avoid noise and speed up runs. + language: [python, actions] + + steps: + # Scheduled workflows run from the default branch. + # We explicitly analyze `develop` on the schedule to keep the scan + # focused on the active dev branch. + - name: Checkout repository (scheduled → develop) + if: ${{ github.event_name == 'schedule' }} + uses: actions/checkout@v6 + with: + ref: develop + + - name: Checkout repository + if: ${{ github.event_name != 'schedule' }} + uses: actions/checkout@v6 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + + print-link: + name: Print results link + runs-on: ubuntu-latest + + needs: codeql + permissions: {} # no special perms needed just to print links + + steps: + - name: Add Code Scanning link to job summary + run: | + echo "## 🔎 CodeQL Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "View Code Scanning alerts here:" >> $GITHUB_STEP_SUMMARY + echo "${{ github.server_url }}/${{ github.repository }}/security/code-scanning" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/test-trigger.yml b/.github/workflows/test-trigger.yml new file mode 100644 index 00000000..440bae3c --- /dev/null +++ b/.github/workflows/test-trigger.yml @@ -0,0 +1,40 @@ +name: Scheduled code tests trigger + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +jobs: + code-tests-trigger: + runs-on: ubuntu-latest + + steps: + - name: Checkout develop branch + uses: actions/checkout@v6 + with: + ref: develop + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Dispatch code tests workflow + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: "test.yml", + ref: "develop" + }); diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..6bf99c45 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,306 @@ +# This is the main workflow for testing the code before and after +# packaging it. +# The workflow is divided into three jobs: +# 1. env-prepare: +# - Prepare the environment for testing +# 2. source-test: +# - Test the code base against the latest code in the repository +# - Create the Python package +# - Upload the Python package for the next job +# 3. package-test: +# - Download the Python package (including extra files) from the previous job +# - Install the downloaded Python package +# - Test the code base against the installed package +# 4. dashboard-build-trigger: +# - Trigger the dashboard build workflow to update the code quality +# metrics on the dashboard + +name: Code and package tests + +on: + # Trigger the workflow on push + push: + branches-ignore: [master, main] # Already verified in PR + # But do not run this workflow on creating a new tag starting with + # 'v', e.g. 'v1.0.3' (see publish-pypi.yml) + tags-ignore: ['v*'] + # Trigger the workflow on pull request + pull_request: + branches: ['**'] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Need permissions to trigger the dashboard build workflow +permissions: + actions: write + contents: read + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + PY_VERSIONS: '3.11 3.13' + PIXI_ENVS: 'py-311-env py-313-env' + +jobs: + # Job 1: Set up environment variables + env-prepare: + runs-on: [ubuntu-latest] + + outputs: + pytest-marks: ${{ steps.set-mark.outputs.pytest_marks }} + + steps: + # Determine if integration tests should be run fully or only the fast ones + # (to save time on branches other than master and develop) + - name: Set mark for integration tests + id: set-mark + run: | + if [[ "${{ env.CI_BRANCH }}" == "master" || "${{ env.CI_BRANCH }}" == "develop" ]]; then + echo "pytest_marks=" >> $GITHUB_OUTPUT + else + echo "pytest_marks=-m fast" >> $GITHUB_OUTPUT + fi + + # Job 2: Test code + source-test: + needs: env-prepare # depend on previous job + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-15, windows-2022] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: ${{ env.PIXI_ENVS }} + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.XX -> py-3XX-env + + echo "Running tests in environment: $env" + pixi run --environment $env unit-tests + done + + - name: Run functional tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.XX -> py-3XX-env + + echo "Running tests in environment: $env" + pixi run --environment $env functional-tests + done + + - name: Run integration tests ${{ needs.env-prepare.outputs.pytest-marks }} + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.XX -> py-3XX-env + + echo "Running tests in environment: $env" + pixi run --environment $env integration-tests ${{ needs.env-prepare.outputs.pytest-marks }} + done + + # Delete all local tags when not on a tagged commit to force versioningit + # to fall back to the configured default-tag, which is '999.0.0' in our case. + # This is needed for testing the package in the next job, as its version + # must be higher than the PyPI version for pip to prefer the local version. + - name: Force using versioningit default tag (non tagged release) + if: startsWith(github.ref , 'refs/tags/v') != true + run: git tag --delete $(git tag) + + - name: Build package wheels for all Python versions + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.11 -> py-311-env + + echo "Building wheel in environment: $env" + pixi run --environment $env dist-build + + echo "Moving built wheel to dist/py$py_ver/" + pixi run mkdir -p dist/py$py_ver + pixi run mv dist/*.whl dist/py$py_ver/ + done + + - name: Remove Python cache files before uploading + shell: bash + run: pixi run clean-pycache + + # More than one file/dir need to be specified in 'path', to preserve the + # structure of the dist/ directory, not only its contents. + - name: Upload package (incl. extras) for next job + uses: ./.github/actions/upload-artifact + with: + name: easyreflectometry_${{ matrix.os }}_${{ runner.arch }} + path: dist/ + + # Job 3: Test the package + package-test: + needs: source-test # depend on previous job + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-15, windows-2022] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Download package (incl. extras) from previous job + uses: ./.github/actions/download-artifact + with: + # name and path should be taken from the upload step of the previous job + name: easyreflectometry_${{ matrix.os }}_${{ runner.arch }} + path: dist/ + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: '' + activate-environment: '' + run-install: false + frozen: false + + - name: Install easyreflectometry from the built wheel + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Initializing pixi project" + pixi init easyreflectometry_py$py_ver + cd easyreflectometry_py$py_ver + + echo "Adding Python $py_ver" + pixi add "python=$py_ver" + + echo "Setting macOS 14.0 as minimum required" + pixi project system-requirements add macos 14.0 + + echo "Looking for wheel in ../dist/py$py_ver/" + ls -l "../dist/py$py_ver/" + + whl_path=(../dist/"py$py_ver"/*.whl) + if [[ ! -f "${whl_path[0]}" ]]; then + echo "❌ No wheel found in ../dist/py$py_ver/" + exit 1 + fi + + # whl_url="file://$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "${whl_path[0]}")" + # echo "Adding easyreflectometry from: $whl_url" + # pixi add --pypi "easyreflectometry[dev] @ ${whl_url}" + + whl_abs_path="$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "${whl_path[0]}")" + + echo "Adding easyreflectometry from: $whl_abs_path" + pixi add --pypi "easyreflectometry[dev] @ ${whl_abs_path}" + + echo "Exiting pixi project directory" + cd .. + done + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Entering pixi project directory easyreflectometry_py$py_ver" + cd easyreflectometry_py$py_ver + + echo "Running tests" + pixi run python -m pytest ../tests/unit/ --color=yes -v + + echo "Exiting pixi project directory" + cd .. + done + + - name: Run functional tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Entering pixi project directory easyreflectometry_py$py_ver" + cd easyreflectometry_py$py_ver + + echo "Running tests" + pixi run python -m pytest ../tests/functional/ --color=yes -v + + echo "Exiting pixi project directory" + cd .. + done + + - name: Run integration tests ${{ needs.env-prepare.outputs.pytest-marks }} + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Entering pixi project directory easyreflectometry_py$py_ver" + cd easyreflectometry_py$py_ver + + echo "Running tests" + pixi run python -m pytest ../tests/integration/ --color=yes -n auto -v ${{ needs.env-prepare.outputs.pytest-marks }} + + echo "Exiting pixi project directory" + cd .. + done + + # Job 4: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: package-test # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/tutorial-tests-trigger.yml b/.github/workflows/tutorial-tests-trigger.yml new file mode 100644 index 00000000..4b160d87 --- /dev/null +++ b/.github/workflows/tutorial-tests-trigger.yml @@ -0,0 +1,40 @@ +name: Scheduled tutorial tests trigger + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +jobs: + tutorial-tests-trigger: + runs-on: ubuntu-latest + + steps: + - name: Checkout develop branch + uses: actions/checkout@v6 + with: + ref: develop + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Dispatch tutorial tests workflow + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: "tutorial-tests.yml", + ref: "develop" + }); diff --git a/.github/workflows/tutorial-tests.yml b/.github/workflows/tutorial-tests.yml new file mode 100644 index 00000000..a4fc940c --- /dev/null +++ b/.github/workflows/tutorial-tests.yml @@ -0,0 +1,60 @@ +name: Tutorial tests + +on: + # Trigger the workflow on push + push: + # Selected branches + branches: [develop] # master and main are already verified in PR + # Trigger the workflow on pull request + pull_request: + branches: ['**'] + # Trigger the workflow on workflow_call (to be called from other workflows) + # Needed, as standard schedule triggers the master branch only, but we want + # to run this workflow on develop branch. + workflow_call: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + # Job 1: Test tutorials as scripts and notebooks on multiple OS + tutorial-tests: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Prepare notebooks + shell: bash + run: pixi run notebook-prepare + + - name: Test tutorials as notebooks + shell: bash + run: pixi run notebook-tests + + # Job 2: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: tutorial-tests # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.gitignore b/.gitignore index ff5a50d4..6dc595c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,49 +1,46 @@ -# QtCreator -*.autosave - -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* - -# QtCreator Python -*.pyproject.user -*.pyproject.user.* - -# QtCreator CMake -CMakeLists.txt.user* - # Python -__pycache__ -.venv +__pycache__/ +.venv/ .coverage .pyc -# Poetry -dist -poetry.lock -*.egg-info +# Pixi +.pixi/ # PyInstaller -build +dist/ +build/ *.spec -# Jupyter +# MkDocs +docs/site/ + +# Jupyter Notebooks .ipynb_checkpoints +# Node +node_modules/ + +# QtCreator +*.autosave +*.qmlproject.user +*.qmlproject.user.* +*.pyproject.user +*.pyproject.user.* +CMakeLists.txt.user* + +# PyCharm +.idea/ + +# VS Code +.vscode/ + # macOS .DS_Store *.app *.dmg -# Docs -docs/_build - -# VSCode -.vscode - # Misc -..* +.cache/ *.log *.zip -.ci/ -.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..9a3855f4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,61 @@ +repos: + - repo: local + hooks: + # ------------- + # Manual checks + # ------------- + - id: pixi-pyproject-check + name: pixi run pyproject-check + entry: pixi run pyproject-check + language: system + pass_filenames: false + stages: [manual] + + - id: license-headers-check + name: pixi run license-check + entry: pixi run license-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-py-lint-check + name: pixi run py-lint-check + entry: pixi run py-lint-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-py-format-check + name: pixi run py-format-check + entry: pixi run py-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-docstring-lint-check + name: pixi run docstring-lint-check + entry: pixi run docstring-lint-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-nonpy-format-check + name: pixi run nonpy-format-check + entry: pixi run nonpy-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-notebook-lint-check + name: pixi run notebook-lint-check + entry: pixi run notebook-lint-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-unit-tests + name: pixi run unit-tests + entry: pixi run unit-tests + language: system + pass_filenames: false + stages: [manual] diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..a08c3c48 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,32 @@ +# Git +.git/ + +# Copier +.copier-answers*.yml + +# Pixi +.pixi +pixi.lock + +# MkDocs +docs/overrides/ +docs/site/ +docs/docs/assets/ + +# Python +.pytest_cache/ + +# MyPy +.mypy_cache/ + +# Ruff +.ruff_cache/ + +# Node +node_modules + +# Misc +.benchmarks +.cache +deps/ +tmp/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 69077f1c..bb888bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ # Version 1.6.0 (1 May 2026) -Add Mighell-based handling of non-positive-variance points in fitting (issue #256). -Non-positive-variance data points are no longer forcibly discarded; instead, a -hybrid objective applies a Mighell substitution for non-positive-variance points -while using standard weighted least squares for the rest. The previous masking -behavior is available via `objective='legacy_mask'`. New `objective` parameter on -`MultiFitter`, `fit()`, and `fit_single_data_set_1d()`. +Add Mighell-based handling of non-positive-variance points in fitting +(issue #256). Non-positive-variance data points are no longer forcibly +discarded; instead, a hybrid objective applies a Mighell substitution +for non-positive-variance points while using standard weighted least +squares for the rest. The previous masking behavior is available via +`objective='legacy_mask'`. New `objective` parameter on `MultiFitter`, +`fit()`, and `fit_single_data_set_1d()`. # Version 1.3.3 (17 June 2025) -Added Chi^2 and fit status to fitting results. -Added explicit dependency on bumps version. +Added Chi^2 and fit status to fitting results. Added explicit dependency +on bumps version. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..a4ac1fbc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,446 @@ +# Contributing to EasyReflectometry + +Thank you for your interest in contributing to **EasyReflectometry**! + +This guide explains how you can: + +- Report issues +- Contribute code +- Improve documentation +- Suggest enhancements +- Interact with the EasyScience community + +Whether you are an experienced developer or contributing for the first +time, this document walks you through the entire process step by step. + +Please make sure you follow the EasyScience organization-wide +[Code of Conduct](https://github.com/easyscience/.github/blob/master/CODE_OF_CONDUCT.md). + +--- + +## Table of Contents + +- [How to Interact With This Project](#how-to-interact-with-this-project) +- [1. Understanding the Development Model](#1-understanding-the-development-model) +- [2. Getting the Code](#2-getting-the-code) +- [3. Setting Up the Development Environment](#3-setting-up-the-development-environment) +- [4. Creating a Branch](#4-creating-a-branch) +- [5. Implementing Your Changes](#5-implementing-your-changes) +- [6. Code Quality Checks](#6-code-quality-checks) +- [7. Opening a Pull Request](#7-opening-a-pull-request) +- [8. Continuous Integration (CI)](#8-continuous-integration-ci) +- [9. Code Review](#9-code-review) +- [10. Documentation Contributions](#10-documentation-contributions) +- [11. Reporting Issues](#11-reporting-issues) +- [12. Security Issues](#12-security-issues) +- [13. Releases](#13-releases) + +--- + +## How to Interact With This Project + +If you are not planning to contribute code, you may want to: + +- 🐞 Report a bug — see [Reporting Issues](#11-reporting-issues) +- 🛡 Report a security issue — see + [Security Issues](#12-security-issues) +- 💬 Ask a question or start a discussion at + [Project Discussions](https://github.com/easyscience/reflectometry-lib/discussions) + +If you plan to contribute code or documentation, continue below. + +--- + +## 1. Understanding the Development Model + +Before you start coding, it is important to understand how development +works in this project. + +### Branching Strategy + +We use the following branches: + +- `master` — stable releases only +- `develop` — active development branch +- Short-lived branches — feature or fix branches created for a single + contribution and deleted after merge + +> [!IMPORTANT] +> +> All normal contributions must target the `develop` branch. +> +> - Do **not** open Pull Requests against `master` +> - Always create your branch from `develop` +> - Always target `develop` when opening a Pull Request + +See ADR easyscience/.github#12 for more details on the branching +strategy. + +--- + +## 2. Getting the Code + +### 2.1. If You Are an External Contributor + +If you are not a core maintainer of this repository, follow these steps. + +1. Open the repository page: + `https://github.com/easyscience/reflectometry-lib` + +2. Click the **Fork** button (top-right corner). This creates your own + copy of the repository. + +3. Clone your fork locally: + + ```bash + git clone https://github.com//reflectometry-lib.git + cd reflectometry-lib + ``` + +4. Add the original repository as `upstream`: + + ```bash + git remote add upstream https://github.com/easyscience/reflectometry-lib.git + ``` + +5. Switch to the `develop` branch and update it: + + ```bash + git fetch upstream + git checkout develop + git pull upstream develop + ``` + +If you have contributed before, make sure your local `develop` branch is +up to date before starting new work. You can update it with: + +```bash +git fetch upstream +git pull upstream develop +``` + +This ensures you are working on the latest version of the project. + +### 2.2. If You Are a Core Team Member + +Core team members can create branches directly in this repository and +therefore do not need to fork it, but the rest of the workflow remains +the same. + +--- + +## 3. Setting Up the Development Environment + +You need: + +- Git +- Pixi + +EasyScience projects use **Pixi** to manage the development environment. + +To install Pixi, follow the official instructions: +https://pixi.prefix.dev/latest/installation/ + +You do **not** need to manually install Python. Pixi automatically: + +- Creates the correct Python environment +- Installs all required dependencies +- Installs development tools (linters, formatters, test tools) + +Set up the environment: + +```bash +pixi install +pixi run post-install # Install additional tooling +``` + +After this step, your development environment is ready. + +See ADR easyscience/.github#63 for more details about using Pixi for +development. + +--- + +## 4. Creating a Branch + +Never work directly on `develop`. + +Create a new branch: + +```bash +git checkout -b my-change develop +``` + +> [!IMPORTANT] +> +> Use a clear and descriptive name, for example: +> +> - `improve-solver-speed` +> - `fix-boundary-condition` +> - `add-tutorial-example` + +Clear branch names make reviews and history easier to understand. + +--- + +## 5. Implementing Your Changes + +While developing, make small, logical commits with clear messages. + +Example: + +```bash +git add . +git commit -m "Improve performance of time integrator for large systems" +``` + +--- + +## 6. Code Quality Checks + +> [!IMPORTANT] +> +> When adding new functionality or making changes, make sure to add or +> update the following as needed: +> +> - 📘 docstrings +> - 🧪 unit tests + +Before opening a Pull Request, always run: + +```bash +pixi run check +``` + +This command: + +- Validates the pyproject.toml file +- Checks for licence headers in code files +- Identifies linting and formatting issues in Python code +- Checks docstring linting and formatting issues in Python code +- Detects formatting issues in non-Python files (MD, YAML, TOML etc.) +- Checks linting issues in Jupyter notebooks (if applicable) +- Runs unit tests + +A successful run should look like this: + +```bash +pixi run pyproject-check.......................Passed +pixi run license-check.........................Passed +pixi run py-lint-check.........................Passed +pixi run py-format-check.......................Passed +pixi run docstring-lint-check..................Passed +pixi run nonpy-format-check....................Passed +pixi run notebook-lint-check...................Passed +pixi run unit-tests............................Passed +``` + +If something fails, read the error message carefully and fix the issue. + +You can run individual checks, for example, to run only unit tests: + +```bash +pixi run unit-tests +``` + +or to run only Python linting checks: + +```bash +pixi run py-lint-check +``` + +Some formatting issues can be fixed automatically: + +```bash +pixi run fix +``` + +If everything is correctly formatted, you will see: + +```text +✅ All auto-formatting steps completed successfully! +``` + +This indicates that the auto-formatting pipeline completed successfully. +If you do not see this message and no error messages appear, try running +the command again. + +If errors are reported, resolve them and re-run: + +```bash +pixi run check +``` + +> [!IMPORTANT] +> +> All checks must pass before your Pull Request can be merged. + +If you are unsure how to fix an issue, ask for help in your Pull Request +discussion. + +--- + +## 7. Opening a Pull Request + +Push your branch: + +```bash +git push origin my-change +``` + +On GitHub: + +- Click **Compare & Pull Request** +- Ensure the base branch is `develop` +- Write a clear and concise title +- Add a description explaining what changed and why +- Add the required `[scope]` label + +### Pull Request Title + +> [!IMPORTANT] +> +> The PR title appears in release notes and changelogs. It should be +> concise and informative. + +Good examples: + +- Improve performance of time integrator for large systems +- Fix incorrect boundary condition handling in solver +- Add adaptive step-size control to ODE solver +- Add tutorial for custom model configuration +- Refactor solver API for improved readability + +### Required `[scope]` Label + +> [!IMPORTANT] +> +> Each Pull Request must include a `[scope]` label, which is used for +> automatically suggesting version bumps when preparing a new release. + +The available scopes are: + +| Label | Description | +| ----------------------- | ----------------------------------------------------------------------- | +| `[scope] bug` | Bug report or fix (major.minor.**PATCH**) | +| `[scope] documentation` | Documentation-only changes (major.minor.patch.**POST**) | +| `[scope] enhancement` | Adds or improves features (major.**MINOR**.patch) | +| `[scope] maintenance` | Code/tooling cleanup without feature or bug fix (major.minor.**PATCH**) | +| `[scope] significant` | Breaking or major changes (**MAJOR**.minor.patch) | + +See ADR easyscience/.github#33 for more details on the standardized +labeling scheme. + +--- + +## 8. Continuous Integration (CI) + +After opening a Pull Request: + +- Automated checks run automatically +- You will see green checkmarks or red crosses + +If checks fail: + +1. Open the failing check +2. Read the logs +3. Fix the issue locally +4. Run `pixi run check` +5. Push your changes + +The Pull Request updates automatically. + +--- + +## 9. Code Review + +All Pull Requests are reviewed by at least one core team member. + +Code review is collaborative and aims to improve quality. + +Do not take comments personally — they are meant to help. + +To update your PR: + +```bash +git add . +git commit -m "Address review comments" +git push +``` + +--- + +## 10. Documentation Contributions + +> [!IMPORTANT] +> +> If your change affects user-facing functionality, update the project +> documentation accordingly — specifically the `nav:` (navigation) +> structure in `mkdocs.yml` and the relevant documentation Markdown +> files in `docs/docs/`. +> +> ```text +> 📁 docs +> ├── 📁 docs - Markdown files for documentation +> │ └── ... +> └── 📄 mkdocs.yml - Configuration file (navigation, theme, etc.) +> ``` + +This may include: + +- API documentation +- Examples +- Tutorials +- Jupyter notebooks + +Preview documentation locally: + +```bash +pixi run docs-serve +``` + +Open the URL shown in the terminal to review your changes. + +--- + +## 11. Reporting Issues + +If you find a bug but cannot work on a fix, please consider opening an +issue. + +When reporting an issue, it helps to: + +- Search existing issues first. +- Provide clear reproduction steps. +- Include logs, screenshots, and environment details. + +Clear and detailed reports help maintainers investigate and resolve +issues more effectively. + +--- + +## 12. Security Issues + +> [!IMPORTANT] +> +> Please do **not** report security vulnerabilities publicly. + +If you discover a potential vulnerability, please contact the +maintainers privately so the issue can be investigated and addressed +responsibly. + +--- + +## 13. Releases + +Once your contribution is merged into `develop`, it will eventually be +included in the next stable release. + +When enough changes have accumulated in `develop`, core team members +merge `develop` into `master` to prepare a new release. The release is +then tagged and published on GitHub and PyPI. + +--- + +Thank you for contributing to EasyReflectometry and the EasyScience +ecosystem! diff --git a/LICENSE b/LICENSE index c1ee0cf3..c4e3e48e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,6 @@ BSD 3-Clause License -Copyright (c) 2024, Easyscience contributors (https://github.com/EasyScience) -All rights reserved. +Copyright (c) 2021-2026 EasyScience contributors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 1e53cdf4..01da1ff1 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,48 @@ -![Logo](https://github.com/easyScience/EasyReflectometryLib/raw/master/docs/src/_static/logo.png) -[![CI badge](https://github.com/easyScience/EasyReflectometryLib/actions/workflows/python-ci.yml/badge.svg)](https://github.com/easyScience/easyReflectometryLib/actions/workflows/python-ci.yml) -[![PyPI badge](https://img.shields.io/pypi/v/easyreflectometry.svg)](https://pypi.python.org/pypi/easyreflectometry) -[![Quality badge](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib/badge)](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib) -[![Docs badge](https://img.shields.io/badge/docs-built-blue)](http://docs.easyreflectometry.org) +

+ + + + + + + EasyReflectometry + +

-# About +**EasyReflectometry** is a software for performing reflectometry +calculations based on a layer model and refining its parameters against +reflectometry data. -A reflectometry python package and an application. + -This repo and documentation is for the `easyreflectometry` Python package that is built on the `easyscience` [framework](https://easyscience.software). -To get more information about the application visit [`easyreflectometry.org`](https://easyreflectometry.org) +**EasyReflectometry** is developed as a Python library. -# Installation +License: +[BSD 3-Clause](https://github.com/easyscience/reflectometry-lib/blob/master/LICENSE) -```sh -python -m pip install easyreflectometry -``` +## Useful Links + +### For Users + +- 📖 + [Documentation](https://easyscience.github.io/reflectometry-lib/latest) +- 🚀 + [Getting Started](https://easyscience.github.io/reflectometry-lib/latest/introduction) +- 🧪 + [Tutorials](https://easyscience.github.io/reflectometry-lib/latest/tutorials) +- 💬 + [Get in Touch](https://easyscience.github.io/reflectometry-lib/latest/introduction/#get-in-touch) +- 🧾 + [Citation](https://easyscience.github.io/reflectometry-lib/latest/introduction/#citation) + +### For Contributors + +- 🧑‍💻 [Source Code](https://github.com/easyscience/reflectometry-lib) +- 🐞 + [Issue Tracker](https://github.com/easyscience/reflectometry-lib/issues) +- 💡 + [Discussions](https://github.com/easyscience/reflectometry-lib/discussions) +- 🤝 + [Contributing Guide](https://github.com/easyscience/reflectometry-lib/blob/master/CONTRIBUTING.md) +- 🛡 + [Code of Conduct](https://github.com/easyscience/.github/blob/master/CODE_OF_CONDUCT.md) diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..f62b13ab --- /dev/null +++ b/codecov.yml @@ -0,0 +1,13 @@ +# Codecov configuration +# https://docs.codecov.com/docs/codecovyml-reference + +coverage: + status: + project: + default: + # Make project coverage informational (won't block PR) + informational: true + patch: + default: + # Require patch coverage but with threshold + threshold: 1% diff --git a/docs/docs/api-reference/assemblies/gradient_layer.md b/docs/docs/api-reference/assemblies/gradient_layer.md new file mode 100644 index 00000000..b5ee7d48 --- /dev/null +++ b/docs/docs/api-reference/assemblies/gradient_layer.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.assemblies.gradient_layer diff --git a/docs/docs/api-reference/assemblies/multilayer.md b/docs/docs/api-reference/assemblies/multilayer.md new file mode 100644 index 00000000..f693c205 --- /dev/null +++ b/docs/docs/api-reference/assemblies/multilayer.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.assemblies.multilayer diff --git a/docs/docs/api-reference/assemblies/repeating_multilayer.md b/docs/docs/api-reference/assemblies/repeating_multilayer.md new file mode 100644 index 00000000..d2215e46 --- /dev/null +++ b/docs/docs/api-reference/assemblies/repeating_multilayer.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.assemblies.repeating_multilayer diff --git a/docs/docs/api-reference/assemblies/surfactant_layer.md b/docs/docs/api-reference/assemblies/surfactant_layer.md new file mode 100644 index 00000000..19f1f56d --- /dev/null +++ b/docs/docs/api-reference/assemblies/surfactant_layer.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.assemblies.surfactant_layer diff --git a/docs/docs/api-reference/data.md b/docs/docs/api-reference/data.md new file mode 100644 index 00000000..700ec762 --- /dev/null +++ b/docs/docs/api-reference/data.md @@ -0,0 +1 @@ +::: easyreflectometry.data.measurement diff --git a/docs/docs/api-reference/elements/layer.md b/docs/docs/api-reference/elements/layer.md new file mode 100644 index 00000000..c37cd7b4 --- /dev/null +++ b/docs/docs/api-reference/elements/layer.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.layers.layer diff --git a/docs/docs/api-reference/elements/layer_area_per_molecule.md b/docs/docs/api-reference/elements/layer_area_per_molecule.md new file mode 100644 index 00000000..d7245c69 --- /dev/null +++ b/docs/docs/api-reference/elements/layer_area_per_molecule.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.layers.layer_area_per_molecule diff --git a/docs/docs/api-reference/elements/material.md b/docs/docs/api-reference/elements/material.md new file mode 100644 index 00000000..7fba8cf4 --- /dev/null +++ b/docs/docs/api-reference/elements/material.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.materials.material diff --git a/docs/docs/api-reference/elements/material_density.md b/docs/docs/api-reference/elements/material_density.md new file mode 100644 index 00000000..24c4c425 --- /dev/null +++ b/docs/docs/api-reference/elements/material_density.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.materials.material_density diff --git a/docs/docs/api-reference/elements/material_mixture.md b/docs/docs/api-reference/elements/material_mixture.md new file mode 100644 index 00000000..899b28e8 --- /dev/null +++ b/docs/docs/api-reference/elements/material_mixture.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.materials.material_mixture diff --git a/docs/docs/api-reference/elements/material_solvated.md b/docs/docs/api-reference/elements/material_solvated.md new file mode 100644 index 00000000..d89901e6 --- /dev/null +++ b/docs/docs/api-reference/elements/material_solvated.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.elements.materials.material_solvated diff --git a/docs/docs/api-reference/fitting.md b/docs/docs/api-reference/fitting.md new file mode 100644 index 00000000..88b465c9 --- /dev/null +++ b/docs/docs/api-reference/fitting.md @@ -0,0 +1 @@ +::: easyreflectometry.fitting diff --git a/docs/docs/api-reference/index.md b/docs/docs/api-reference/index.md new file mode 100644 index 00000000..85b9e5c7 --- /dev/null +++ b/docs/docs/api-reference/index.md @@ -0,0 +1,72 @@ +--- +icon: material/code-braces-box +--- + +# :material-code-braces-box: API Reference + +This section contains the auto-generated reference detailing the +functions and modules available in EasyReflectometry. + +## Model + +Model is a sample, a background and a resolution. + +- [Model](model.md) + +## Sample + +Sample is built from assemblies. + +- [Sample](sample.md) + +## Project + +Project provides a higher-level interface for managing models, +experiments, and ORSO import. + +- [Project](project.md) + +## Fitting + +Fitting helpers and objective functions. + +- [Fitting](fitting.md) + +## Assemblies + +Assemblies are collections of layers that are used to represent a +specific physical setup. + +- [Multilayer](assemblies/multilayer.md) +- [Repeating Multilayer](assemblies/repeating_multilayer.md) +- [Surfactant Layer](assemblies/surfactant_layer.md) +- [Gradient Layer](assemblies/gradient_layer.md) + +## Elements + +Elements are the building blocks that are required to construct a +sample. + +### Layers + +Layers are basic elements and used to represent a single layer of +material with a thickness and a roughness. + +- [Layer](elements/layer.md) +- [Layer Area Per Molecule](elements/layer_area_per_molecule.md) + +### Materials + +Materials are the most basic elements and are used to represent a +material with given physical properties. + +- [Material](elements/material.md) +- [Material Density](elements/material_density.md) +- [Material Mixture](elements/material_mixture.md) +- [Material Solvated](elements/material_solvated.md) + +## Data + +Collection of helper functions. + +- [Data](data.md) diff --git a/docs/docs/api-reference/model.md b/docs/docs/api-reference/model.md new file mode 100644 index 00000000..cbb1bbf9 --- /dev/null +++ b/docs/docs/api-reference/model.md @@ -0,0 +1 @@ +::: easyreflectometry.model.model diff --git a/docs/docs/api-reference/project.md b/docs/docs/api-reference/project.md new file mode 100644 index 00000000..d778788c --- /dev/null +++ b/docs/docs/api-reference/project.md @@ -0,0 +1 @@ +::: easyreflectometry.project diff --git a/docs/docs/api-reference/sample.md b/docs/docs/api-reference/sample.md new file mode 100644 index 00000000..387cd62c --- /dev/null +++ b/docs/docs/api-reference/sample.md @@ -0,0 +1 @@ +::: easyreflectometry.sample.collections.sample diff --git a/docs/docs/assets/images/favicon.png b/docs/docs/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..ec9e329e7d7b1637990ae7fb79a5449f81652c92 GIT binary patch literal 14318 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 J^Nko0{|5(1fTsWe literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/logo_dark.svg b/docs/docs/assets/images/logo_dark.svg new file mode 100644 index 00000000..d59c52d2 --- /dev/null +++ b/docs/docs/assets/images/logo_dark.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + Logo + + + + + + + + Text + + + + + \ No newline at end of file diff --git a/docs/docs/assets/images/logo_light.svg b/docs/docs/assets/images/logo_light.svg new file mode 100644 index 00000000..f02ec4a1 --- /dev/null +++ b/docs/docs/assets/images/logo_light.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + Logo + + + + + + + + Text + + + + + \ No newline at end of file diff --git a/docs/docs/assets/javascripts/extra.js b/docs/docs/assets/javascripts/extra.js new file mode 100644 index 00000000..9596ee07 --- /dev/null +++ b/docs/docs/assets/javascripts/extra.js @@ -0,0 +1,27 @@ +;(function () { + 'use strict' + + // Variables + const header = document.getElementsByTagName('header')[0] + + console.log(window.pageYOffset) + + // Hide-show header shadow + function toggleHeaderShadow() { + if (window.pageYOffset <= 0) { + header.classList.remove('md-header--shadow') + } else { + header.classList.add('md-header--shadow') + } + } + + // Onload + window.onload = function () { + toggleHeaderShadow() + } + + // Onscroll + window.onscroll = function () { + toggleHeaderShadow() + } +})() diff --git a/docs/docs/assets/javascripts/mathjax.js b/docs/docs/assets/javascripts/mathjax.js new file mode 100644 index 00000000..333524ec --- /dev/null +++ b/docs/docs/assets/javascripts/mathjax.js @@ -0,0 +1,33 @@ +window.MathJax = { + tex: { + //inlineMath: [['\\(', '\\)']], + //displayMath: [['\\[', '\\]']], + // Add support for $...$ and \(...\) delimiters + inlineMath: [ + ['$', '$'], + ['\\(', '\\)'], + ], + // Add support for $$...$$ and \[...]\ delimiters + displayMath: [ + ['$$', '$$'], + ['\\[', '\\]'], + ], + processEscapes: true, + processEnvironments: true, + }, + options: { + //ignoreHtmlClass: ".*|", + //processHtmlClass: "arithmatex" + // Skip code blocks only + skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'], + // Only ignore explicit opt-out + ignoreHtmlClass: 'no-mathjax|tex2jax_ignore', + }, +} + +document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() +}) diff --git a/docs/docs/assets/stylesheets/extra.css b/docs/docs/assets/stylesheets/extra.css new file mode 100644 index 00000000..a625be80 --- /dev/null +++ b/docs/docs/assets/stylesheets/extra.css @@ -0,0 +1,359 @@ +/*************/ +/* Variables */ +/*************/ + +:root { + --sz-link-color--lightmode: #0184c7; + --sz-hovered-link-color--lightmode: #37bdf9; + --sz-body-background-color--lightmode: #fafafa; + --sz-body-text-color--lightmode: #525252; + --sz-body-heading-color--lightmode: #434343; + --sz-code-background-color--lightmode: #ececec; + + --sz-link-color--darkmode: #37bdf9; + --sz-hovered-link-color--darkmode: #2890c0; + --sz-body-background-color--darkmode: #262626; + --sz-body-text-color--darkmode: #a3a3a3; + --sz-body-heading-color--darkmode: #e5e5e5; + --sz-code-background-color--darkmode: #212121; +} + +/****************/ +/* Color styles */ +/****************/ + +/* Default styles https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/main/_typeset.scss */ + +/* Light mode */ + +/* Default light mode https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/main/_colors.scss */ + +[data-md-color-scheme="default"] { + + /* Primary color shades */ + --md-primary-fg-color: var(--sz-body-background-color--lightmode); /* Navigation background */ + --md-primary-bg-color: var(--sz-body-text-color--lightmode); /* E.g., Header title and icons */ + --md-primary-bg-color--light: var(--sz-body-text-color--lightmode); /* E.g., Header search */ + + /* Accent color shades */ + --md-accent-fg-color: var(--sz-hovered-link-color--lightmode); /* E.g., Hovered `a` elements & copy icon in code */ + + /* Default color shades */ + --md-default-fg-color: var(--sz-body-text-color--lightmode); + --md-default-fg-color--light: var(--sz-body-heading-color--lightmode); /* E.g., `h1` color & TOC viewed items & `$` in code */ + --md-default-fg-color--lighter: var(--sz-body-text-color--lightmode); /* E.g., `¶` sign near `h1-h8` */ + --md-default-fg-color--lightest: var(--sz-body-text-color--lightmode); /* E.g., Copy icon in code */ + --md-default-bg-color: var(--sz-body-background-color--lightmode); + + /* Code color shades */ + --md-code-bg-color: var(--sz-code-background-color--lightmode); + + /* Typeset color shades */ + --md-typeset-color: var(--sz-body-text-color--lightmode); + + /* Typeset `a` color shades */ + --md-typeset-a-color: var(--sz-link-color--lightmode); + + /* Footer color shades */ + --md-footer-fg-color: var(--sz-body-text-color--lightmode); /* E.g., Next -> */ + --md-footer-fg-color--light: var(--sz-body-text-color--lightmode); /* E.g., © 2022 EasyDiffraction, Material for MkDocs */ + --md-footer-fg-color--lighter: var(--sz-body-text-color--lightmode); /* E.g. Made with */ + --md-footer-bg-color: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., Next -> */ + --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., © 2022 EasyDiffraction */ + + /* Custom colors */ + --sz-red-color: #F44336; + --sz-blue-color: #03A9F4; + --sz-green-color: #4CAF50; + --sz-orange-color: #FF9800; + + /* Logo display */ + --md-footer-logo-dark-mode: none; + --md-footer-logo-light-mode: block; +} + +/* Dark mode */ + +/* Default dark mode: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/palette/_scheme.scss */ + +[data-md-color-scheme="slate"] { + + /* Primary color shades */ + --md-primary-fg-color: var(--sz-body-background-color--darkmode); /* Navigation background */ + --md-primary-bg-color: var(--sz-body-text-color--darkmode); /* E.g., Header title and icons */ + --md-primary-bg-color--light: var(--sz-body-text-color--darkmode); /* E.g., Header search */ + + /* Accent color shades */ + --md-accent-fg-color: var(--sz-hovered-link-color--darkmode); /* E.g., Hovered `a` elements & copy icon in code */ + + /* Default color shades */ + --md-default-fg-color: var(--sz-body-text-color--darkmode); + --md-default-fg-color--light: var(--sz-body-heading-color--darkmode); /* E.g., `h1` color & TOC viewed items & `$` in code */ + --md-default-fg-color--lighter: var(--sz-body-text-color--darkmode); /* E.g., `¶` sign near `h1-h8` */ + --md-default-fg-color--lightest: var(--sz-body-text-color--darkmode); /* E.g., Copy icon in code */ + --md-default-bg-color: var(--sz-body-background-color--darkmode); + + /* Code color shades */ + --md-code-bg-color: var(--sz-code-background-color--darkmode); + + /* Typeset color shades */ + --md-typeset-color: var(--sz-body-text-color--darkmode); + + /* Typeset `a` color shades */ + --md-typeset-a-color: var(--sz-link-color--darkmode); + + /* Footer color shades */ + --md-footer-fg-color: var(--sz-body-text-color--darkmode); /* E.g., Next -> */ + --md-footer-fg-color--light: var(--sz-body-text-color--darkmode); /* E.g., © 2022 EasyDiffraction, Material for MkDocs */ + --md-footer-fg-color--lighter: var(--sz-body-text-color--darkmode); /* E.g. Made with */ + --md-footer-bg-color: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., Next -> */ + --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., © 2022 EasyDiffraction */ + + /* Custom colors */ + --sz-red-color: #EF9A9A; + --sz-blue-color: #81D4FA; + --sz-green-color: #A5D6A7; + --sz-orange-color: #FFCC80; + + /* Logo display */ + --md-footer-logo-dark-mode: block; + --md-footer-logo-light-mode: none; +} + +/*****************/ +/* Custom styles */ +/*****************/ + +/* Logo */ + +#logo_light_mode { + display: var(--md-footer-logo-light-mode); +} + +#logo_dark_mode { + display: var(--md-footer-logo-dark-mode); +} + +/* Customize default styles of MkDocs Material */ + +/* Hide navigation title */ +label.md-nav__title[for="__drawer"] { + height: 0; +} + +/* Hide site title (first topic) while keeping page title and version selector */ +.md-header__topic:first-child .md-ellipsis { + display: none; +} + +/* Increase logo size */ +.md-logo :is(img, svg) { + height: 1.8rem !important; +} + +/* Hide GH repo with counts (top right page corner) */ +.md-header__source { + display: none; +} + +/* Hide GH repo with counts (navigation bar in mobile view) */ +.md-nav__source { + display: none; +} + +/* Ensure all horizontal lines in the navigation list are removed or hidden */ +.md-nav__item { + /* Removes any border starting from the second level */ + border: none !important; + /* Modifies the background color to hide the first horizontal line */ + background-color: var(--md-default-bg-color); +} + +/* Increase TOC (on the right) width */ +.md-nav--secondary { + margin-left: -10px; + margin-right: -4px; +} + +/* */ +.md-nav__item > .md-nav__link { + padding-left: 0.5em; /* Default */ +} + +/* Change line height of the tabel cells */ +.md-typeset td, +.md-typeset th { + line-height: 1.25 !important; +} + +/* Change vertical alignment of the icon inside the tabel cells */ +.md-typeset td .twemoji { + vertical-align: sub !important; +} + +/* Change the width of the primary sidebar */ +/* +.md-sidebar--primary { + width: 240px; +} +*/ + +/* Change the overall width of the page */ +.md-grid { + max-width: 1280px; +} + +/* Needed for mkdocs-jupyter to show download and other buttons on top of the notebook */ +.md-content__button { + position: relative !important; +} + +/* Background color of the search input field */ +.md-search__input { + background-color: var(--md-code-bg-color) !important; +} + +/* Customize default style of mkdocs-jupyter plugin */ + +/* Set the width of the notebook to fill 100% and not reduce by the width of .md-content__button's +Adjust the margins and paddings to fit the defaults in MkDocs Material and do not crop the label in the header +*/ +.jupyter-wrapper { + width: 100% !important; + display: flex !important; +} + +.jp-Notebook { + padding: 0 !important; + margin-top: -3em !important; + + /* Ensure notebook content stretches across the page */ + width: 100% !important; + max-width: 100% !important; + + /* mkdocs-material + some notebook HTML end up as flex */ + align-items: stretch !important; +} + +.jp-Notebook .jp-Cell { + /* Key: flex children often need min-width: 0 to prevent weird shrink */ + width: 100% !important; + max-width: 100% !important; + min-width: 0 !important; + + /* Removes jupyter cell paddings */ + padding-left: 0 !important; +} + +/* Removes jupyter cell prefixes, like In[123]: */ +.prompt, +.jp-InputPrompt, +.jp-OutputPrompt { + display: none !important; +} + +/* Removes jupyter output cell padding to align with input cell text */ +.jp-RenderedText { + padding-left: 0.85em !important; +} + +/* Extra styling the panda dataframes, on top of the style included in the code */ +table.dataframe { + float: left; + margin-left: 0.75em !important; + margin-bottom: 0.5em !important; + font-size: var(--jp-code-font-size) !important; + color: var(--md-primary-bg-color) !important; + /* Allow table cell wrapping in MkDocs-Jupyter outputs */ + /* + table-layout: auto !important; + width: auto !important; + */ +} + +/* Allow wrap for the last column */ +/* +table.dataframe td:last-child, +table.dataframe th:last-child { + white-space: normal !important; + word-break: break-word !important; +} +*/ + +/* Custom styles for the CIF files */ + +.cif { + padding-left: 1em; + padding-right: 1em; + padding-top: 1px; + padding-bottom: 1px; + background-color: var(--md-code-bg-color); + font-size: small; +} +.red { + color: var(--sz-red-color); +} +.green { + color: var(--sz-green-color); +} +.blue { + color: var(--sz-blue-color); +} +.orange { + color: var(--sz-orange-color); +} +.grey { + color: grey; +} + +/**********/ +/* Labels */ +/**********/ + +.label-cif { + padding-top: 0.5ex; + padding-bottom: 0.5ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 1ex; + color: var(--md-default-fg-color) !important; + background-color: var(--md-code-bg-color); +} + +p .label-cif, li .label-cif { + vertical-align: 5%; + font-size: 12px; +} + +.label-cif:hover { + color: white !important; +} + +.label-experiment { + padding-top: 0.25ex; + padding-bottom: 0.6ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 1ex; + color: var(--md-default-fg-color) !important; + background-color: rgba(55, 189, 249, 0.1); +} + +p .label-experiment, li .label-experiment { + vertical-align: 5%; + font-size: 12px; +} + +h1 .label-experiment { + padding-top: 0.05ex; + padding-bottom: 0.4ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 0.75ex; + color: var(--md-default-fg-color) !important; + background-color: rgba(55, 189, 249, 0.1); +} + +.label-experiment:hover { + color: white !important; +} diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 00000000..f11ef87f --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,21 @@ +![](assets/images/logo_dark.svg#gh-dark-mode-only)![](assets/images/logo_light.svg#gh-light-mode-only) + +# Reflectometry data analysis + +Here is a brief overview of the main documentation sections: + +- [:material-information-slab-circle: Introduction](introduction/index.md) + – Provides a description of EasyReflectometry, including its purpose, + licensing, latest release details, and contact information. +- [:material-cog-box: Installation & Setup](installation-and-setup/index.md) + – Guides users through system requirements, environment configuration, + and the installation process. +- [:material-book-open-variant: User Guide](user-guide/index.md) – + Covers core concepts, key terminology, workflow steps, and essential + parameters for effective use of EasyReflectometry. +- [:material-school: Tutorials](tutorials/index.md) – Offers practical, + step-by-step examples demonstrating common workflows and data analysis + tasks. +- [:material-code-braces-box: API Reference](api-reference/index.md) – + An auto-generated reference detailing the available functions and + modules in EasyReflectometry. diff --git a/docs/docs/installation-and-setup/index.md b/docs/docs/installation-and-setup/index.md new file mode 100644 index 00000000..4baef822 --- /dev/null +++ b/docs/docs/installation-and-setup/index.md @@ -0,0 +1,282 @@ +--- +icon: material/cog-box +--- + +# :material-cog-box: Installation & Setup + +**EasyReflectometry** is a cross-platform Python library compatible with +**Python 3.11** through **3.13**. + +To install and set up EasyReflectometry, we recommend using +[**Pixi**](https://pixi.prefix.dev), a modern package manager for +Windows, macOS, and Linux. + +??? note "Main benefits of using Pixi" + + - **Ease of use**: Pixi simplifies the installation process, making it + accessible even for users with limited experience in package management. + - **Python version control**: Pixi allows specifying and managing different + Python versions for each project, ensuring compatibility. + - **Isolated environments**: Pixi creates isolated environments for each + project, preventing conflicts between different package versions. + - **PyPI and Conda support**: Pixi can install packages from both PyPI and + Conda repositories, providing access to a wide range of libraries. + +An alternative installation method using the traditional **pip** package +manager is also provided. + +## Installing with Pixi recommended { #installing-with-pixi data-toc-label="Installing with Pixi" } + +This section describes the simplest way to set up EasyReflectometry +using **Pixi**. + +#### Installing Pixi + +- Install Pixi by following the instructions on the + [official Pixi Installation Guide](https://pixi.prefix.dev/latest/installation). + +#### Setting up EasyReflectometry with Pixi + + + +- Choose a project location (local drive recommended). + + ??? warning ":fontawesome-brands-windows: Windows + OneDrive" + + We **do not recommend creating a Pixi project inside OneDrive or other + synced folders**. + + By default, Pixi creates the virtual environment inside the project + directory (in `.pixi/`). On Windows, synced folders such as OneDrive + may cause file‑system issues (e.g., path-length limitations or + restricted link operations), which can lead to unexpected install + errors or environments being recreated. + + Instead, create your project in a **local directory on your drive** + where you have full write permissions. + + + +- Initialize a new Pixi project and navigate into it: + ```txt + pixi init easyreflectometry + cd easyreflectometry + ``` +- Set the Python version for the Pixi environment (e.g., 3.13): + ```txt + pixi add python=3.13 + ``` +- Add EasyReflectometry to the Pixi environment from PyPI: + ```txt + pixi add --pypi easyreflectometry + ``` +- Add a Pixi task to run EasyReflectometry commands easily: + ```txt + pixi task add easyreflectometry "python -m easyreflectometry" + ``` + +#### Updating Pixi and EasyReflectometry + +- To update all packages in the Pixi environment, including + EasyReflectometry: + ```txt + pixi update + ``` +- To update Pixi itself to the latest version: + ```txt + pixi self-update + ``` + +#### Uninstalling Pixi + +- Follow the + [official Pixi Guide](https://pixi.prefix.dev/latest/installation/#uninstall). + +## Classical Installation + +This section describes how to install EasyReflectometry using the +traditional method with **pip**. It is assumed that you are familiar +with Python package management and virtual environments. + +### Environment Setup optional { #environment-setup data-toc-label="Environment Setup" } + +We recommend using a **virtual environment** to isolate dependencies and +avoid conflicts with system-wide packages. If any issues arise, you can +simply delete and recreate the environment. + +#### Creating and Activating a Virtual Environment: + + + +- Create a new virtual environment: + ```txt + python3 -m venv venv + ``` +- Activate the environment: + + === ":material-apple: macOS" + ```txt + . venv/bin/activate + ``` + === ":material-linux: Linux" + ```txt + . venv/bin/activate + ``` + === ":fontawesome-brands-windows: Windows" + ```txt + . venv/Scripts/activate # Windows with Unix-like shells + .\venv\Scripts\activate.bat # Windows with CMD + .\venv\Scripts\activate.ps1 # Windows with PowerShell + ``` + +- The terminal should now show `(venv)`, indicating that the virtual environment + is active. + + + +#### Deactivating and Removing the Virtual Environment: + + + +- Exit the environment: + ```txt + deactivate + ``` +- If this environment is no longer needed, delete it: + + === ":material-apple: macOS" + ```txt + rm -rf venv + ``` + === ":material-linux: Linux" + ```txt + rm -rf venv + ``` + === ":fontawesome-brands-windows: Windows" + ```txt + rmdir /s /q venv + ``` + + + +### Installing from PyPI { #from-pypi } + +EasyReflectometry is available on **PyPI (Python Package Index)** and +can be installed using `pip`. To do so, use the following command: + +```txt +pip install easyreflectometry +``` + +To install a specific version of EasyReflectometry, e.g., 1.0.3: + +```txt +pip install 'easyreflectometry==1.0.3' +``` + +To upgrade to the latest version: + +```txt +pip install --upgrade easyreflectometry +``` + +To upgrade to the latest version and force reinstallation of all +dependencies (useful if files are corrupted): + +```txt +pip install --upgrade --force-reinstall easyreflectometry +``` + +To check the installed version: + +```txt +pip show easyreflectometry +``` + +### Installing from GitHub alternative { #from-github data-toc-label="Installing from GitHub" } + +Installing unreleased versions is generally not recommended but may be +useful for testing. + +To install EasyReflectometry from the `develop` branch of GitHub, for +example: + +```txt +pip install git+https://github.com/easyscience/reflectometry-lib@develop +``` + +To include extra dependencies (e.g., dev): + +```txt +pip install 'easyreflectometry[dev] @ git+https://github.com/easyscience/reflectometry-lib@develop' +``` + +## How to Run Tutorials + +EasyReflectometry includes a collection of **Jupyter Notebook examples** +that demonstrate key functionality. These tutorials serve as +**step-by-step guides** to help users understand the data analysis +workflow. They are available as **static HTML pages** in the +[:material-school: Tutorials](../tutorials/index.md) section. + +In the next sections, we explain how to set up Jupyter and run the +tutorials interactively in two different ways: locally or online via +Google Colab. + +If you decide to run the tutorials locally, you need to download them +first. This can be done individually via the :material-download: +**Download Notebook** button available on each tutorial page, or all at +once using the command line, as shown below. + +### Run Tutorials Locally with Pixi recommended { #running-with-pixi data-toc-label="Run Tutorials Locally with Pixi" } + +- Navigate to your existing Pixi project, created as described in the + [Installing with Pixi](#installing-with-pixi) section. +- Add JupyterLab, Interactive Python shell and the Pixi kernel for + Jupyter: + ```txt + pixi add --pypi jupyterlab ipython pixi-kernel + ``` +- Download all the EasyReflectometry tutorials to the `tutorials/` + directory. +- Start the JupyterLab server in the `tutorials/` directory to access + the notebooks: + ```txt + pixi run jupyter lab tutorials/ + ``` +- Your web browser should open automatically. Click on one of the + `*.ipynb` files and select the `Python (Pixi)` kernel to get started. + +### Classical Run Tutorials Locally + +- Install Jupyter Notebook, Interactive Python shell and the IPython + kernel: + ```txt + pip install notebook ipython ipykernel + ``` +- Add the virtual environment as a Jupyter kernel: + ```txt + python -m ipykernel install --user --name=venv --display-name "EasyReflectometry Python kernel" + ``` +- Download all the EasyReflectometry tutorials to the `tutorials/` + directory. +- Start the Jupyter Notebook server in the `tutorials/` directory to + access the notebooks: + ```txt + jupyter notebook tutorials/ + ``` +- Your web browser should open automatically. Click on one of the + `*.ipynb` files and select the `EasyReflectometry Python kernel` to + get started. + +### Run Tutorials via Google Colab + +**Google Colab** lets you run Jupyter Notebooks in the cloud without any +local installation. This is the fastest way to start experimenting with +EasyReflectometry. + +- Ensure you have a **Google account**. +- Go to the **[:material-school: Tutorials](../tutorials/index.md)** + section. +- Click the :google-colab: **Open in Google Colab** button on any + tutorial. diff --git a/docs/docs/introduction/index.md b/docs/docs/introduction/index.md new file mode 100644 index 00000000..4335dfdf --- /dev/null +++ b/docs/docs/introduction/index.md @@ -0,0 +1,68 @@ +--- +icon: material/information-slab-circle +--- + +# :material-information-slab-circle: Introduction + +## Description + +**EasyReflectometry** is a software for performing reflectometry +calculations based on a layer model and refining its parameters against +reflectometry data. + +**EasyReflectometry** is developed as a Python library. + + + +## License + +**EasyReflectometry** library is released under the +[BSD 3-Clause License](https://raw.githubusercontent.com/easyscience/reflectometry-lib/master/LICENSE). + +## Releases + +The latest version of the **EasyReflectometry** library is +[{{ vars.release_version }}](https://github.com/easyscience/reflectometry-lib/releases/latest). + +For a complete list of new features, bug fixes, and improvements, see +the +[GitHub Releases page](https://github.com/easyscience/reflectometry-lib/releases). + +## Citation + +If you use **EasyReflectometry** library in your work, please cite the +specific version you used. + +All official releases of the **EasyReflectometry** library are archived +on Zenodo, each with a version-specific Digital Object Identifier (DOI). + +Citation details in various styles (e.g., APA, MLA) and formats (e.g., +BibTeX, JSON) are available on the +[Zenodo archive page](https://doi.org/10.5281/zenodo.18163581). + +## Contributing + +We welcome contributions of any kind! + +**EasyReflectometry** is intended to be a community-driven, open-source +project supported by a diverse group of contributors. + +The project is maintained by the +[European Spallation Source (ESS)](https://ess.eu). + +If you would like to report a bug or request a new feature, please use +the +[GitHub Issue Tracker](https://github.com/easyscience/reflectometry-lib/issues) +(A free GitHub account is required.) + +To contribute code, documentation, or tests, please see our +[:material-account-plus: Contributing Guidelines](https://github.com/easyscience/reflectometry-lib/blob/master/CONTRIBUTING.md) +for detailed development instructions. + +## Get in Touch + +For general questions or feedback, please contact us at +[support@easyreflectometry.org](mailto:support@easyreflectometry.org). diff --git a/docs/src/tutorials/advancedfitting/multi_contrast.ipynb b/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb similarity index 92% rename from docs/src/tutorials/advancedfitting/multi_contrast.ipynb rename to docs/docs/tutorials/advancedfitting/multi_contrast.ipynb index 51e4e225..02f675ba 100644 --- a/docs/src/tutorials/advancedfitting/multi_contrast.ipynb +++ b/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb @@ -20,6 +20,16 @@ "First configure matplotlib to place figures in notebook and import needed modules. Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "54684688", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -27,29 +37,21 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", - "import refnx\n", "import pooch\n", + "from easyscience.fitting import AvailableMinimizers\n", "\n", - "import easyreflectometry\n", - "\n", + "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", "from easyreflectometry.plot import plot\n", - "from easyreflectometry.sample import Material\n", - "from easyreflectometry.sample import SurfactantLayer\n", "from easyreflectometry.sample import Layer\n", - "from easyreflectometry.sample import Multilayer\n", "from easyreflectometry.sample import LayerAreaPerMolecule\n", + "from easyreflectometry.sample import Material\n", + "from easyreflectometry.sample import Multilayer\n", "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.model import Model\n", - "from easyreflectometry.model import PercentageFwhm\n", - "from easyreflectometry.calculators import CalculatorFactory\n", - "from easyreflectometry.fitting import MultiFitter\n", - "from easyscience.fitting import AvailableMinimizers\n", - "\n", - "print(f'easyreflectometry: {easyreflectometry.__version__}')\n", - "print(f'refnx: {refnx.__version__}')" + "from easyreflectometry.sample import SurfactantLayer" ] }, { @@ -73,8 +75,8 @@ "source": [ "file_path = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/advancedfitting/multiple.ort\",\n", - " known_hash=\"241bcb819cdae47fbbb310a99c2456c7332312719496b936a153dc7dee83e62c\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/advancedfitting/multiple.ort',\n", + " known_hash='241bcb819cdae47fbbb310a99c2456c7332312719496b936a153dc7dee83e62c',\n", ")\n", "data = load(file_path)" ] @@ -130,8 +132,7 @@ "metadata": {}, "outputs": [], "source": [ - "dspc = {'d-head': 'C10D18NO8P', 'd-tail': 'C34D70',\n", - " 'h-head': 'C10H18NO8P', 'h-tail': 'C34H70'}" + "dspc = {'d-head': 'C10D18NO8P', 'd-tail': 'C34D70', 'h-head': 'C10H18NO8P', 'h-tail': 'C34H70'}" ] }, { @@ -235,7 +236,7 @@ " solvent=air,\n", " solvent_fraction=tail_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", + " roughness=roughness,\n", ")\n", "head_layer_d13d2o = LayerAreaPerMolecule(\n", " molecular_formula=dspc['d-head'],\n", @@ -243,12 +244,9 @@ " solvent=d2o,\n", " solvent_fraction=head_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", - ")\n", - "d13d2o = SurfactantLayer(\n", - " tail_layer=tail_layer_d13d2o,\n", - " head_layer=head_layer_d13d2o\n", + " roughness=roughness,\n", ")\n", + "d13d2o = SurfactantLayer(tail_layer=tail_layer_d13d2o, head_layer=head_layer_d13d2o)\n", "d13d2o.constrain_area_per_molecule = True\n", "d13d2o.conformal_roughness = True\n", "d13d2o.constrain_solvent_roughness(d2o_layer.roughness)" @@ -275,7 +273,7 @@ " solvent=air,\n", " solvent_fraction=tail_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", + " roughness=roughness,\n", ")\n", "head_layer_d70d2o = LayerAreaPerMolecule(\n", " molecular_formula=dspc['h-head'],\n", @@ -283,12 +281,9 @@ " solvent=d2o,\n", " solvent_fraction=head_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", - ")\n", - "d70d2o = SurfactantLayer(\n", - " tail_layer=tail_layer_d70d2o,\n", - " head_layer=head_layer_d70d2o\n", + " roughness=roughness,\n", ")\n", + "d70d2o = SurfactantLayer(tail_layer=tail_layer_d70d2o, head_layer=head_layer_d70d2o)\n", "d70d2o.constrain_area_per_molecule = True\n", "d70d2o.conformal_roughness = True\n", "d70d2o.constrain_solvent_roughness(d2o_layer.roughness)" @@ -315,7 +310,7 @@ " solvent=air,\n", " solvent_fraction=tail_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", + " roughness=roughness,\n", ")\n", "head_layer_d83acmw = LayerAreaPerMolecule(\n", " molecular_formula=dspc['d-head'],\n", @@ -323,12 +318,9 @@ " solvent=acmw,\n", " solvent_fraction=head_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", - ")\n", - "d83acmw = SurfactantLayer(\n", - " tail_layer=tail_layer_d83acmw,\n", - " head_layer=head_layer_d83acmw\n", + " roughness=roughness,\n", ")\n", + "d83acmw = SurfactantLayer(tail_layer=tail_layer_d83acmw, head_layer=head_layer_d83acmw)\n", "d83acmw.constrain_area_per_molecule = True\n", "d83acmw.conformal_roughness = True\n", "d83acmw.constrain_solvent_roughness(acmw_layer.roughness)" @@ -420,19 +412,19 @@ " sample=d13d2o_sample,\n", " scale=0.1,\n", " background=data['data']['R_d13DSPC-D2O'].values.min(),\n", - " resolution_function=resolution_function\n", + " resolution_function=resolution_function,\n", ")\n", "d70d2o_model = Model(\n", " sample=d70d2o_sample,\n", " scale=0.1,\n", " background=data['data']['R_d70DSPC-D2O'].values.min(),\n", - " resolution_function=resolution_function\n", + " resolution_function=resolution_function,\n", ")\n", "d83acmw_model = Model(\n", " sample=d83acmw_sample,\n", " scale=0.1,\n", " background=data['data']['R_d83DSPC-ACMW'].values.min(),\n", - " resolution_function=resolution_function\n", + " resolution_function=resolution_function,\n", ")" ] }, diff --git a/docs/src/tutorials/advancedfitting/multiple.ort b/docs/docs/tutorials/advancedfitting/multiple.ort similarity index 100% rename from docs/src/tutorials/advancedfitting/multiple.ort rename to docs/docs/tutorials/advancedfitting/multiple.ort diff --git a/docs/docs/tutorials/basic/assemblies_library.md b/docs/docs/tutorials/basic/assemblies_library.md new file mode 100644 index 00000000..da419f56 --- /dev/null +++ b/docs/docs/tutorials/basic/assemblies_library.md @@ -0,0 +1,71 @@ +# Creating Multilayers and Surfactant Layers + +EasyReflectometry is designed to be used with a broad range of different +assemblies. Assemblies are collective layers behaving as a single +object, for example, a multilayer or a surfactant layer. These +assemblies offer flexibility for the user and enable more powerful +analysis by making chemical and physical constraints available with +limited code. In this page, we will document the assemblies that are +available with simple examples of the constructors that exist. Full API +documentation is also available for the +`easyreflectometry.sample.assemblies` module. + +## Multilayer + +This assembly should be used for a series of layers that should be +thought of as a single object. For example, in the simple fitting +tutorial this assembly type is used to combine the silicon and silicon +dioxide layer that is formed into a single object. All of the separate +layers in these objects will be fitted individually, i.e. there are no +constraints present, however, there is some cognitive benefit to +grouping layers together. + +To create a `Multilayer` object, we use the following construction. + +```python +from easyreflectometry.sample import Layer +from easyreflectometry.sample import Material +from easyreflectometry.sample import Multilayer + +si = Material(sld=2.07, isld=0, name='Si') +sio2 = Material(sld=3.47, isld=0, name='SiO2') +si_layer = Layer(material=si, thickness=0, roughness=0, name='Si layer') +sio2_layer = Layer(material=sio2, thickness=30, roughness=3, name='SiO2 layer') + +subphase = Multilayer(layers=[si_layer, sio2_layer], name='Si/SiO2 subphase') +``` + +This will create a `Multilayer` object named `subphase` which we can use +in some `Structure` for our analysis. + +## RepeatingMultilayer + +The `RepeatingMultilayer` assembly type is an extension of the +`Multilayer` for the analysis of systems with a multilayer that has some +number of repeats. This assembly type imposes some constraints, +specifically that all of the repeats have the exact same structure (i.e. +thicknesses, roughnesses, and scattering length densities), which brings +with it some computational saving as the reflectometry coefficients only +need to be calculated once for this structure and propagated for the +correct number of repeats. There is a tutorial that discusses the +utilisation of this assembly type for a nickel-titanium multilayer +system. + +The creation of a `RepeatingMultilayer` object is very similar to that +for the `Multilayer`, with the addition of a number of repetitions. + +```python +from easyreflectometry.sample import Layer +from easyreflectometry.sample import Material +from easyreflectometry.sample import RepeatingMultilayer + +ti = Material(sld=-1.9493, isld=0, name='Ti') +ni = Material(sld=9.4245, isld=0, name='Ni') +ti_layer = Layer(material=ti, thickness=40, roughness=0, name='Ti Layer') +ni_layer = Layer(material=ni, thickness=70, roughness=0, name='Ni Layer') +ni_ti = RepeatingMultilayer(layers=[ti_layer, ni_layer], repetitions=10, name='Ni/Ti Multilayer') +``` + +The number of repeats is a parameter that can be varied in the +optimisation process, however given this is a value that depends on the +synthesis of the sample this is unlikely to be necessary. diff --git a/docs/docs/tutorials/basic/layer_library.md b/docs/docs/tutorials/basic/layer_library.md new file mode 100644 index 00000000..4a679690 --- /dev/null +++ b/docs/docs/tutorials/basic/layer_library.md @@ -0,0 +1,69 @@ +# Defining Layers + +Similar to a range of different materials, there are a few different +ways that a layer can be defined in EasyReflectometry. + +## Layer + +The `Layer` is the simplest possible type of layer, taking a `Material` +and two floats associated with the thickness and upper (that is closer +to the source of the incident radiation) roughness. So we construct a +`Layer` as follows for a 100 Å thick layer of boron with a roughness of +10 Å. + +```python +from easyreflectometry.sample import Material +from easyreflectometry.sample import Layer + +boron = Material(sld=6.908, isld=-0.278, name='Boron') +boron_layer = Layer(material=boron, thickness=100, roughness=10, name='Boron Layer') +``` + +This type of layer is used extensively in the tutorials. + +To create a semi-infinite layer one needs to set the thickness to 0 and +the roughness to 0. + +```python +from easyreflectometry.sample import Material +from easyreflectometry.sample import Layer + +si = Material(sld=2.07, isld=0, name='Si') +semi_infinite_layer = Layer(material=si, thickness=0, roughness=0, name='Si layer') +``` + +## LayerAreaPerMolecule + +The `LayerAreaPerMolecule` layer type is the foundation of the +`SurfactantLayer` assemblies type (further information on this can be +found in the assemblies library). The purpose of the +`LayerAreaPerMolecule` is to allow a layer to be defined in terms of the +chemical formula of the material and the area per molecule of the layer. +The area per molecule is a common description of surface density in the +surfactant monolayer and bilayer community. + +We can construct a 10 Å thick `LayerAreaPerMolecule` of +phosphatidylcholine, with an area per molecule of 48 Å squared and a +roughness of 3 Å that has 20% solvent surface coverage with D2O using +the following. + +```python +from easyreflectometry.sample import Material +from easyreflectometry.sample import LayerAreaPerMolecule + +d2o = Material(sld=6.36, isld=0, name='D2O') +molecular_formula = 'C10H18NO8P' +pc = LayerAreaPerMolecule( + molecular_formula=molecular_formula, + thickness=10, + solvent=d2o, + solvent_fraction=0.2, + area_per_molecule=48, + roughness=3, + name='PC Layer', +) +``` + +It is expected that the typical user will not interface directly with +the `LayerAreaPerMolecule` assembly type, but instead the +`SurfactantLayer` assemblies library will be used instead. diff --git a/docs/docs/tutorials/basic/material_library.md b/docs/docs/tutorials/basic/material_library.md new file mode 100644 index 00000000..78bdfcf1 --- /dev/null +++ b/docs/docs/tutorials/basic/material_library.md @@ -0,0 +1,78 @@ +# Defining Materials + +In order to support a wide range of applications (and to build complex +assemblies) there are a few different types of material that can be +utilised in EasyReflectometry. These can include constraints or enable +the user to define the material based on chemical or physical +properties. Full API documentation for the +`easyreflectometry.sample.elements.material` module is also available, +but here we will give some simple uses for them. + +## Material + +The simplest type of material that is available is the `Material`. This +allows the user to define a single type of material, with a real and +imaginary component to the scattering length density. The construction +of a `Material` is achieved as shown below. + +```python +from easyreflectometry.sample import Material + +boron = Material(sld=6.908, isld=-0.278, name='Boron') +``` + +The above object will have the properties of `sld` and `isld`, which +will have values of `6.908 1/angstrom^2` and `-0.278 1/angstrom^2` +respectively. As is shown in the tutorials, a material can be used to +construct a `Layer` from which +[slab models](https://www.reflectometry.org/isis_school/3_reflectometry_slab_models/the_slab_model.html) +are created. + +## MaterialDensity + +In addition to defining a material by its scattering length density, it +may be useful to define a material by the mass density and chemical +formula. This is possible with the `MaterialDensity` material type, +which uses the scattering length and atomic mass from the chemical +formula and the density to determine the scattering length density. It +is then possible to vary the density, which defines the scattering +length density in turn. The `MaterialDensity` material can be created as +follows. + +```python +from easyreflectometry.sample import MaterialDensity + +chemical_structure = 'SiO2' +si = MaterialDensity(chemical_structure=chemical_structure, density=2.65, name='SiO2 Material') +``` + +The density should be in units of grams per cubic centimeter and the +scattering length is calculated from `'SiO2'`. + +## MaterialSolvated + +Sometimes it is desirable to have a layer that consists of a material +and a solvent in some ratio. An example of this is shown in the +solvation tutorial, where a polymer film solvated with D2O is modelled. +To produce a material that is described by such a mixture, there is +`MaterialSolvated`. This is constructed from two constituent `Materials` +and the fractional amount of the material in the solvent. So to produce +a `MaterialSolvated` that is 20% D2O in a polymer, the following is +used. + +```python +from easyreflectometry.sample import Material +from easyreflectometry.sample import MaterialSolvated + +polymer = Material(sld=2.0, isld=0.0, name='Polymer') +d2o = Material(sld=6.36, isld=0, name='D2O') + +solvated_polymer = MaterialSolvated(material=polymer, solvent=d2o, solvent_fraction=0.2, name='Solvated Polymer') +``` + +For the `solvated_polymer` object, the `sld` will be +`2.872 1/angstrom^2` (the weighted average of the two scattering length +densities). The `MaterialSolvated` includes a constraint such that if +the value of either constituent scattering length densities (both real +and imaginary components) or the fraction changes, then the resulting +material `sld` and `isld` will change appropriately. diff --git a/docs/docs/tutorials/basic/model.md b/docs/docs/tutorials/basic/model.md new file mode 100644 index 00000000..6b9c76c3 --- /dev/null +++ b/docs/docs/tutorials/basic/model.md @@ -0,0 +1,87 @@ +# Creating a Model + +The main component of an experiment in EasyReflectometry is the `Model`. +This is a description of the `Sample` and the environment in which the +experiment is performed. The `Model` is used to calculate the +reflectivity of the `Sample` at a given set of angles (Q-points). The +resolution functions are used to quantify the experimental uncertainties +in wavelength and angle, allowing the `Model` to accurately describe the +data. + +## Model + +A `Model` instance contains a `Sample` and variables describing +experimental settings. To be able to compute reflectivities it is also +necessary to have a `Calculator` (interface). + +```python +from easyreflectometry.calculators import CalculatorFactory +from easyreflectometry.model import Model +from easyreflectometry.sample import Sample + +default_sample = Sample() +model = Model(sample=default_sample, scale=1.0, background=1e-6) + +interface = CalculatorFactory() +model.interface = interface +``` + +This will create a `Model` instance with the `default_sample` and the +environment variables `scale` factor set to 1.0 and a `background` of +1e-6. Following the `interface` is set to the default calculator that is +`Refnx`. + +## Resolution Functions + +A resolution function enables the EasyReflectometry model to incorporate +the experimental uncertainties in wavelength and incident angle into the +model. In its essence the resolution function controls the smearing to +apply when determining the reflectivity at a given Q-point. For a given +Q-point the smearing to apply is given as a weighted average of the +neighboring Q-point, which weights are by a normal distribution. This +normal distribution is then defined by a Q-point dependent Full Width at +the Half Maximum (FWHM) that is given by the resolution function. + +### PercentageFwhm + +Often we rely on a resolution function that has a simple functional +dependency of the Q-point. By this is understood that the applied +smearing in a Q-point has a FWHM that is simply a percentage of the +value of the Q-point. + +```python +from easyreflectometry.model import Model +from easyreflectometry.model import PercentageFwhm + +resolution_function = PercentageFwhm(1.1) + +m = Model(resolution_function=resolution_function) +``` + +This will create a `Model` instance where the resolution function is +defined as 1.1% of the Q-point value, which again is the FWHM for the +smearing. + +### LinearSpline + +Alternatively the FWHM value might be determined and declared directly +for each measured Q-point. When this is the case the provided Q-points +and the corresponding FWHM values can be used to declare a linear spline +function and thereby enable a determination of the reflectivity at an +arbitrary point within the provided range of discrete Q-points. + +```python +from easyreflectometry.model import Model +from easyreflectometry.model import LinearSpline + +m = Model() + +resolution_function = LinearSpline(q_data_points=[0.01, 0.2, 0.31], fwhm_values=[0.001, 0.043, 0.026]) + +m.resolution_function = resolution_function +``` + +This will create a `Model` instance where the resolution function +defining the FWHM is determined from a linear interpolation. In the +present case the provided data Q-points are (`[0.01, 0.2, 0.31]`) and +the corresponding FWHM function values are (`[0.001, 0.043, 0.026]`). diff --git a/docs/src/tutorials/fitting/d70d2o.ort b/docs/docs/tutorials/fitting/d70d2o.ort similarity index 100% rename from docs/src/tutorials/fitting/d70d2o.ort rename to docs/docs/tutorials/fitting/d70d2o.ort diff --git a/docs/src/tutorials/fitting/dspc.png b/docs/docs/tutorials/fitting/dspc.png similarity index 100% rename from docs/src/tutorials/fitting/dspc.png rename to docs/docs/tutorials/fitting/dspc.png diff --git a/docs/src/tutorials/fitting/eq_monolayer.svg b/docs/docs/tutorials/fitting/eq_monolayer.svg similarity index 100% rename from docs/src/tutorials/fitting/eq_monolayer.svg rename to docs/docs/tutorials/fitting/eq_monolayer.svg diff --git a/docs/src/tutorials/fitting/eq_solvated.svg b/docs/docs/tutorials/fitting/eq_solvated.svg similarity index 100% rename from docs/src/tutorials/fitting/eq_solvated.svg rename to docs/docs/tutorials/fitting/eq_solvated.svg diff --git a/docs/src/tutorials/fitting/example.ort b/docs/docs/tutorials/fitting/example.ort similarity index 100% rename from docs/src/tutorials/fitting/example.ort rename to docs/docs/tutorials/fitting/example.ort diff --git a/docs/src/tutorials/fitting/material_solvated.ipynb b/docs/docs/tutorials/fitting/material_solvated.ipynb similarity index 93% rename from docs/src/tutorials/fitting/material_solvated.ipynb rename to docs/docs/tutorials/fitting/material_solvated.ipynb index 4665e87b..d393eb34 100644 --- a/docs/src/tutorials/fitting/material_solvated.ipynb +++ b/docs/docs/tutorials/fitting/material_solvated.ipynb @@ -23,6 +23,16 @@ "First configure matplotlib to place figures in notebook and import needed modules. Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "0143544a", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -30,26 +40,23 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", "import numpy as np\n", - "import scipp as sc\n", "import pooch\n", "import refnx\n", + "import scipp as sc\n", "\n", "import easyreflectometry\n", - "\n", + "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", + "from easyreflectometry.plot import plot\n", "from easyreflectometry.sample import Layer\n", - "from easyreflectometry.sample import Sample\n", "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import MaterialSolvated\n", "from easyreflectometry.sample import Multilayer\n", - "from easyreflectometry.model import Model\n", - "from easyreflectometry.model import PercentageFwhm\n", - "from easyreflectometry.calculators import CalculatorFactory\n", - "from easyreflectometry.fitting import MultiFitter\n", - "from easyreflectometry.plot import plot" + "from easyreflectometry.sample import Sample" ] }, { @@ -92,8 +99,8 @@ "source": [ "file_path = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort\",\n", - " known_hash=\"82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort',\n", + " known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n", ")\n", "data = load(file_path)" ] @@ -137,12 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "solvated_film_material = MaterialSolvated(\n", - " material=film,\n", - " solvent=d2o,\n", - " solvent_fraction=0.25,\n", - " name='Solvated Film'\n", - ")" + "solvated_film_material = MaterialSolvated(material=film, solvent=d2o, solvent_fraction=0.25, name='Solvated Film')" ] }, { @@ -196,13 +198,7 @@ "\n", "resolution_function = PercentageFwhm(0.02)\n", "sample = Sample(superphase, Multilayer(solvated_film), Multilayer(subphase), name='Film Structure')\n", - "model = Model(\n", - " sample=sample,\n", - " scale=1,\n", - " background=1e-6,\n", - " resolution_function=resolution_function,\n", - " name='Film Model'\n", - ")" + "model = Model(sample=sample, scale=1, background=1e-6, resolution_function=resolution_function, name='Film Model')" ] }, { diff --git a/docs/src/tutorials/fitting/monolayer.ipynb b/docs/docs/tutorials/fitting/monolayer.ipynb similarity index 94% rename from docs/src/tutorials/fitting/monolayer.ipynb rename to docs/docs/tutorials/fitting/monolayer.ipynb index d0ef8aa0..e4a7b06d 100644 --- a/docs/src/tutorials/fitting/monolayer.ipynb +++ b/docs/docs/tutorials/fitting/monolayer.ipynb @@ -20,6 +20,16 @@ "First configure matplotlib to place figures in notebook and import needed modules. Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "ece9d352", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -27,27 +37,22 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", - "import refnx\n", "import pooch\n", + "import refnx\n", "\n", "import easyreflectometry\n", - "\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", "from easyreflectometry.plot import plot\n", - "from easyreflectometry.sample import Material\n", - "from easyreflectometry.sample import SurfactantLayer\n", - "from easyreflectometry.sample import LayerAreaPerMolecule\n", "from easyreflectometry.sample import Layer\n", + "from easyreflectometry.sample import LayerAreaPerMolecule\n", + "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.model import Model\n", - "from easyreflectometry.model import PercentageFwhm\n", - "from easyreflectometry.fitting import MultiFitter\n", - "from easyreflectometry.plot import plot\n", - "from easyscience.fitting import AvailableMinimizers\n" + "from easyreflectometry.sample import SurfactantLayer" ] }, { @@ -90,8 +95,8 @@ "source": [ "file_path = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/d70d2o.ort\",\n", - " known_hash=\"3e4750536621be8eec493fa21a287e408d384f29cacb113b71d02690d99f0998\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/d70d2o.ort',\n", + " known_hash='3e4750536621be8eec493fa21a287e408d384f29cacb113b71d02690d99f0998',\n", ")\n", "data = load(file_path)\n", "plot(data)" @@ -254,22 +259,19 @@ " molecular_formula=tail_formula,\n", " thickness=tail_thickness,\n", " solvent=air,\n", - " solvent_fraction=tail_solvent_fraction, \n", + " solvent_fraction=tail_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", + " roughness=roughness,\n", ")\n", "head_layer = LayerAreaPerMolecule(\n", " molecular_formula=head_formula,\n", " thickness=head_thickness,\n", " solvent=d2o,\n", - " solvent_fraction=head_solvent_fraction, \n", + " solvent_fraction=head_solvent_fraction,\n", " area_per_molecule=area_per_molecule,\n", - " roughness=roughness\n", - ")\n", - "dspc = SurfactantLayer(\n", - " tail_layer=tail_layer,\n", - " head_layer=head_layer\n", + " roughness=roughness,\n", ")\n", + "dspc = SurfactantLayer(tail_layer=tail_layer, head_layer=head_layer)\n", "dspc.constrain_area_per_molecule = True\n", "dspc.conformal_roughness = True\n", "dspc" @@ -330,12 +332,7 @@ "source": [ "resolution_function = PercentageFwhm(5)\n", "sample = Sample(Multilayer(air_layer), dspc, Multilayer(d2o_layer))\n", - "model = Model(\n", - " sample=sample,\n", - " scale=1,\n", - " background=data['data']['R_0'].values.min(),\n", - " resolution_function=resolution_function\n", - ")" + "model = Model(sample=sample, scale=1, background=data['data']['R_0'].values.min(), resolution_function=resolution_function)" ] }, { diff --git a/docs/src/tutorials/fitting/monolayer.png b/docs/docs/tutorials/fitting/monolayer.png similarity index 100% rename from docs/src/tutorials/fitting/monolayer.png rename to docs/docs/tutorials/fitting/monolayer.png diff --git a/docs/src/tutorials/fitting/monolayer.svg b/docs/docs/tutorials/fitting/monolayer.svg similarity index 100% rename from docs/src/tutorials/fitting/monolayer.svg rename to docs/docs/tutorials/fitting/monolayer.svg diff --git a/docs/src/tutorials/fitting/polymer_film.png b/docs/docs/tutorials/fitting/polymer_film.png similarity index 100% rename from docs/src/tutorials/fitting/polymer_film.png rename to docs/docs/tutorials/fitting/polymer_film.png diff --git a/docs/src/tutorials/fitting/polymer_film.svg b/docs/docs/tutorials/fitting/polymer_film.svg similarity index 100% rename from docs/src/tutorials/fitting/polymer_film.svg rename to docs/docs/tutorials/fitting/polymer_film.svg diff --git a/docs/src/tutorials/fitting/repeating.ipynb b/docs/docs/tutorials/fitting/repeating.ipynb similarity index 94% rename from docs/src/tutorials/fitting/repeating.ipynb rename to docs/docs/tutorials/fitting/repeating.ipynb index 0ebde2e1..e062ac5d 100644 --- a/docs/src/tutorials/fitting/repeating.ipynb +++ b/docs/docs/tutorials/fitting/repeating.ipynb @@ -24,6 +24,16 @@ "First configure matplotlib to place figures in notebook and import needed modules. Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "419add7b", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -31,27 +41,23 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", "import numpy as np\n", - "import scipp as sc\n", "import pooch\n", "import refl1d\n", + "import scipp as sc\n", "\n", "import easyreflectometry\n", - "\n", + "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", - "from easyreflectometry.sample import Layer\n", - "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.sample import Material\n", - "from easyreflectometry.sample import RepeatingMultilayer\n", - "from easyreflectometry.sample import Multilayer\n", + "from easyreflectometry.fitting import MultiFitter\n", "from easyreflectometry.model import Model\n", "from easyreflectometry.model import PercentageFwhm\n", - "from easyreflectometry.calculators import CalculatorFactory\n", - "from easyreflectometry.fitting import MultiFitter\n", "from easyreflectometry.plot import plot\n", - "from easyscience.fitting import AvailableMinimizers" + "from easyreflectometry.sample import Layer\n", + "from easyreflectometry.sample import Material\n", + "from easyreflectometry.sample import Multilayer\n", + "from easyreflectometry.sample import RepeatingMultilayer\n", + "from easyreflectometry.sample import Sample" ] }, { @@ -95,8 +101,8 @@ "source": [ "file_path = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/repeating_layers.ort\",\n", - " known_hash=\"a5ffca9fd24f1d362266251723aec7ce9f34f123e39a38dfc4d829c758e6bf90\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/repeating_layers.ort',\n", + " known_hash='a5ffca9fd24f1d362266251723aec7ce9f34f123e39a38dfc4d829c758e6bf90',\n", ")\n", "data = load(file_path)" ] @@ -203,13 +209,7 @@ "source": [ "resolution_function = PercentageFwhm(0)\n", "sample = Sample(Multilayer(superphase), rep_multilayer, Multilayer(subphase), name='Multilayer Structure')\n", - "model = Model(\n", - " sample=sample,\n", - " scale=1,\n", - " background=0,\n", - " resolution_function=resolution_function,\n", - " name='Multilayer Model'\n", - ")" + "model = Model(sample=sample, scale=1, background=0, resolution_function=resolution_function, name='Multilayer Model')" ] }, { diff --git a/docs/src/tutorials/fitting/repeating.png b/docs/docs/tutorials/fitting/repeating.png similarity index 100% rename from docs/src/tutorials/fitting/repeating.png rename to docs/docs/tutorials/fitting/repeating.png diff --git a/docs/src/tutorials/fitting/repeating.svg b/docs/docs/tutorials/fitting/repeating.svg similarity index 100% rename from docs/src/tutorials/fitting/repeating.svg rename to docs/docs/tutorials/fitting/repeating.svg diff --git a/docs/src/tutorials/fitting/repeating_layers.ort b/docs/docs/tutorials/fitting/repeating_layers.ort similarity index 100% rename from docs/src/tutorials/fitting/repeating_layers.ort rename to docs/docs/tutorials/fitting/repeating_layers.ort diff --git a/docs/src/tutorials/fitting/simple_fitting.ipynb b/docs/docs/tutorials/fitting/simple_fitting.ipynb similarity index 96% rename from docs/src/tutorials/fitting/simple_fitting.ipynb rename to docs/docs/tutorials/fitting/simple_fitting.ipynb index ea761e75..8eea570a 100644 --- a/docs/src/tutorials/fitting/simple_fitting.ipynb +++ b/docs/docs/tutorials/fitting/simple_fitting.ipynb @@ -21,6 +21,16 @@ "Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "38b12098", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -28,25 +38,22 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", "import matplotlib.pyplot as plt\n", "import pooch\n", "import refl1d\n", "import refnx\n", "\n", "import easyreflectometry\n", - "\n", + "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", + "from easyreflectometry.plot import plot\n", "from easyreflectometry.sample import Layer\n", - "from easyreflectometry.sample import Sample\n", "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", - "from easyreflectometry.model import Model\n", - "from easyreflectometry.model import PercentageFwhm\n", - "from easyreflectometry.calculators import CalculatorFactory\n", - "from easyreflectometry.fitting import MultiFitter\n", - "from easyreflectometry.plot import plot" + "from easyreflectometry.sample import Sample" ] }, { @@ -90,8 +97,8 @@ "source": [ "file_path = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort\",\n", - " known_hash=\"82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort',\n", + " known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n", ")\n", "data = load(file_path)" ] @@ -311,13 +318,7 @@ "outputs": [], "source": [ "resolution_function = PercentageFwhm(0.02)\n", - "model = Model(\n", - " sample=sample,\n", - " scale=1,\n", - " background=1e-6,\n", - " resolution_function=resolution_function,\n", - " name='Film Model'\n", - ")" + "model = Model(sample=sample, scale=1, background=1e-6, resolution_function=resolution_function, name='Film Model')" ] }, { @@ -552,11 +553,7 @@ "\n", "resolution_function_refl1d = PercentageFwhm(0.02)\n", "model_refl1d = Model(\n", - " sample=sample_refl1d,\n", - " scale=1,\n", - " background=1e-6,\n", - " resolution_function=resolution_function_refl1d,\n", - " name='Film Model (Refl1D)'\n", + " sample=sample_refl1d, scale=1, background=1e-6, resolution_function=resolution_function_refl1d, name='Film Model (Refl1D)'\n", ")\n", "\n", "sio2_layer_refl1d.thickness.bounds = (15, 50)\n", @@ -598,7 +595,7 @@ "\n", "qz = data['coords']['Qz_0'].values\n", "reflectivity = data['data']['R_0'].values\n", - "uncertainty = data['data']['R_0'].variances**0.5\n", + "uncertainty = data['data']['R_0'].variances ** 0.5\n", "\n", "plt.figure(figsize=(8, 5))\n", "plt.errorbar(qz, reflectivity, yerr=uncertainty, fmt='o', markersize=3, color='black', alpha=0.6, label='Data')\n", diff --git a/docs/docs/tutorials/index.md b/docs/docs/tutorials/index.md new file mode 100644 index 00000000..7b59c331 --- /dev/null +++ b/docs/docs/tutorials/index.md @@ -0,0 +1,56 @@ +--- +icon: material/school +--- + +# :material-school: Tutorials + +This section presents a collection of **Jupyter Notebook** tutorials +that demonstrate how to use EasyReflectometry for various tasks. These +tutorials serve as self-contained, step-by-step **guides** to help users +grasp the workflow of data analysis using EasyReflectometry. + +Instructions on how to run the tutorials are provided in the +[:material-cog-box: Installation & Setup](../installation-and-setup/index.md#how-to-run-tutorials) +section of the documentation. + +## Getting Started + +- [Creating a Model](basic/model.md) – Learn how to define a + reflectometry model with sample, scale, background, and resolution + functions. +- [Defining Materials](basic/material_library.md) – Explore different + material types: `Material`, `MaterialDensity`, `MaterialSolvated`, and + `MaterialMixture`. +- [Defining Layers](basic/layer_library.md) – Understand layer types + including `Layer` and `LayerAreaPerMolecule`. +- [Creating Assemblies](basic/assemblies_library.md) – Build complex + structures with `Multilayer`, `RepeatingMultilayer`, and + `SurfactantLayer`. + +## Simulation + +These are basic simulation examples using the EasyReflectometry library. + +- [Bilayer Simulation](simulation/bilayer.ipynb) +- [Magnetism Simulation](simulation/magnetism.ipynb) +- [Resolution Functions](simulation/resolution_functions.ipynb) + +## Fitting + +These are basic fitting examples using the EasyReflectometry library. + +- [Simple Fitting](fitting/simple_fitting.ipynb) +- [Repeating Multilayer Fitting](fitting/repeating.ipynb) +- [Monolayer Fitting](fitting/monolayer.ipynb) +- [Solvated Material Fitting](fitting/material_solvated.ipynb) + +## Advanced Fitting + +These are advanced fitting examples using the EasyReflectometry library. + +- [Multi-Contrast Fitting](advancedfitting/multi_contrast.ipynb) + +## Extra + +Additional examples and supplementary material using the +EasyReflectometry library. diff --git a/docs/src/tutorials/simulation/bilayer.ipynb b/docs/docs/tutorials/simulation/bilayer.ipynb similarity index 95% rename from docs/src/tutorials/simulation/bilayer.ipynb rename to docs/docs/tutorials/simulation/bilayer.ipynb index 3d7faccd..b16b8284 100644 --- a/docs/src/tutorials/simulation/bilayer.ipynb +++ b/docs/docs/tutorials/simulation/bilayer.ipynb @@ -32,6 +32,16 @@ "First, we import the necessary modules and configure matplotlib for inline plotting." ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d213b99", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -39,21 +49,18 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", - "import numpy as np\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", "\n", - "import easyreflectometry\n", "from easyreflectometry.calculators import CalculatorFactory\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", "from easyreflectometry.sample import Bilayer\n", + "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import LayerAreaPerMolecule\n", "from easyreflectometry.sample import Material\n", - "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import Multilayer\n", - "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.model import Model\n", - "from easyreflectometry.model import PercentageFwhm" + "from easyreflectometry.sample import Sample" ] }, { @@ -105,7 +112,7 @@ " solvent_fraction=0.3, # 30% solvent in head region\n", " area_per_molecule=48.2,\n", " roughness=3.0,\n", - " name='DPPC Head'\n", + " name='DPPC Head',\n", ")\n", "\n", "# Create a tail layer for the bilayer\n", @@ -117,7 +124,7 @@ " solvent_fraction=0.0, # No solvent in the tail region\n", " area_per_molecule=48.2,\n", " roughness=3.0,\n", - " name='DPPC Tail'\n", + " name='DPPC Tail',\n", ")" ] }, @@ -145,9 +152,9 @@ "bilayer = Bilayer(\n", " front_head_layer=head_layer,\n", " front_tail_layer=front_tail_layer,\n", - " constrain_heads=True, # Head layers share thickness and area per molecule\n", + " constrain_heads=True, # Head layers share thickness and area per molecule\n", " conformal_roughness=True, # All layers share the same roughness\n", - " name='DPPC Bilayer'\n", + " name='DPPC Bilayer',\n", ")\n", "\n", "print(bilayer)" @@ -222,7 +229,7 @@ "\n", "# We can set them independently\n", "bilayer.back_head_layer.solvent_fraction = 0.5\n", - "print(f'\\nAfter setting back head solvent fraction to 0.5:')\n", + "print('\\nAfter setting back head solvent fraction to 0.5:')\n", "print(f'Front head solvent fraction: {bilayer.front_head_layer.solvent_fraction:.2f}')\n", "print(f'Back head solvent fraction: {bilayer.back_head_layer.solvent_fraction:.2f}')" ] @@ -290,7 +297,7 @@ " Multilayer(sio2_layer, name='SiO2'),\n", " bilayer,\n", " Multilayer(d2o_subphase, name='D2O Subphase'),\n", - " name='Bilayer on Si/SiO2'\n", + " name='Bilayer on Si/SiO2',\n", ")\n", "\n", "print(sample)" @@ -314,13 +321,7 @@ "outputs": [], "source": [ "# Create the model\n", - "model = Model(\n", - " sample=sample,\n", - " scale=1.0,\n", - " background=1e-7,\n", - " resolution_function=PercentageFwhm(5),\n", - " name='Bilayer Model'\n", - ")\n", + "model = Model(sample=sample, scale=1.0, background=1e-7, resolution_function=PercentageFwhm(5), name='Bilayer Model')\n", "\n", "# Set up the calculator\n", "interface = CalculatorFactory()\n", @@ -451,7 +452,7 @@ "\n", "# Now set asymmetric hydration (common in supported bilayers)\n", "bilayer.front_head_layer.solvent_fraction = 0.1 # Substrate side - less hydrated\n", - "bilayer.back_head_layer.solvent_fraction = 0.4 # Solution side - more hydrated\n", + "bilayer.back_head_layer.solvent_fraction = 0.4 # Solution side - more hydrated\n", "\n", "# Get asymmetric SLD profile\n", "z_asym, sld_asym = model.interface().sld_profile(model.unique_name)\n", @@ -502,7 +503,7 @@ " solvent_fraction=0.3,\n", " area_per_molecule=48.2,\n", " roughness=3.0,\n", - " name='DPPC Head H2O'\n", + " name='DPPC Head H2O',\n", ")\n", "\n", "# Create tail layer for H2O contrast (same deuterated lipid, different solvent)\n", @@ -513,7 +514,7 @@ " solvent_fraction=0.0,\n", " area_per_molecule=48.2,\n", " roughness=3.0,\n", - " name='DPPC Tail H2O'\n", + " name='DPPC Tail H2O',\n", ")\n", "\n", "# Create H2O bilayer\n", @@ -522,7 +523,7 @@ " front_tail_layer=tail_layer_h2o,\n", " constrain_heads=True,\n", " conformal_roughness=True,\n", - " name='DPPC Bilayer H2O'\n", + " name='DPPC Bilayer H2O',\n", ")" ] }, @@ -568,16 +569,12 @@ " Multilayer(sio2_layer, name='SiO2'),\n", " bilayer_h2o,\n", " Multilayer(h2o_subphase, name='H2O Subphase'),\n", - " name='Bilayer on Si/SiO2 in H2O'\n", + " name='Bilayer on Si/SiO2 in H2O',\n", ")\n", "\n", "# Create model for H2O contrast\n", "model_h2o = Model(\n", - " sample=sample_h2o,\n", - " scale=1.0,\n", - " background=1e-7,\n", - " resolution_function=PercentageFwhm(5),\n", - " name='Bilayer Model H2O'\n", + " sample=sample_h2o, scale=1.0, background=1e-7, resolution_function=PercentageFwhm(5), name='Bilayer Model H2O'\n", ")\n", "model_h2o.interface = interface" ] diff --git a/docs/src/tutorials/simulation/magnetism.ipynb b/docs/docs/tutorials/simulation/magnetism.ipynb similarity index 87% rename from docs/src/tutorials/simulation/magnetism.ipynb rename to docs/docs/tutorials/simulation/magnetism.ipynb index 1f35fdf1..8efdb9e4 100644 --- a/docs/src/tutorials/simulation/magnetism.ipynb +++ b/docs/docs/tutorials/simulation/magnetism.ipynb @@ -20,6 +20,16 @@ "First configure matplotlib to place figures in notebook and import needed modules" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "644e53e3", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -27,24 +37,21 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", - "import scipp as sc\n", "import refl1d\n", "import refl1d.names\n", + "import scipp as sc\n", "\n", "import easyreflectometry\n", - "\n", "from easyreflectometry.calculators import CalculatorFactory\n", + "from easyreflectometry.calculators.refl1d.wrapper import _get_polarized_probe\n", "from easyreflectometry.model import Model\n", "from easyreflectometry.model import PercentageFwhm\n", "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", - "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.calculators.refl1d.wrapper import _get_polarized_probe" + "from easyreflectometry.sample import Sample" ] }, { @@ -150,18 +157,13 @@ "metadata": {}, "outputs": [], "source": [ - "refl1d_sld_4 = refl1d.names.SLD(name=\"Sld 4\", rho=4.0, irho=0)\n", - "refl1d_sld_8 = refl1d.names.SLD(name=\"Sld 8\", rho=8.0, irho=0)\n", - "refl1d_vacuum = refl1d.names.SLD(name=\"Vacuum\", rho=0, irho=0)\n", - "refl1d_si = refl1d.names.SLD(name=\"Si\", rho=2.047, irho=0)\n", + "refl1d_sld_4 = refl1d.names.SLD(name='Sld 4', rho=4.0, irho=0)\n", + "refl1d_sld_8 = refl1d.names.SLD(name='Sld 8', rho=8.0, irho=0)\n", + "refl1d_vacuum = refl1d.names.SLD(name='Vacuum', rho=0, irho=0)\n", + "refl1d_si = refl1d.names.SLD(name='Si', rho=2.047, irho=0)\n", "\n", "# Refl1d model is inverted as compared to EasyReflectometry, so the order of the layers is reversed\n", - "refl1d_sample = (\n", - " refl1d_si(0, 0) | \n", - " refl1d_sld_8(150, 0) |\n", - " refl1d_sld_4(100, 0) | \n", - " refl1d_vacuum(0, 0)\n", - ") " + "refl1d_sample = refl1d_si(0, 0) | refl1d_sld_8(150, 0) | refl1d_sld_4(100, 0) | refl1d_vacuum(0, 0)" ] }, { @@ -206,6 +208,7 @@ " num=1000,\n", ")\n", "\n", + "\n", "def plot_apply_makeup():\n", " ax = plt.gca()\n", " ax.set_xlim([-0.01, 0.35])\n", @@ -233,11 +236,11 @@ "source": [ "# Refl1d\n", "probe = refl1d.names.QProbe(\n", - " Q=model_coords,\n", - " dQ=np.zeros(len(model_coords)),\n", - " intensity=1,\n", - " background=0,\n", - " )\n", + " Q=model_coords,\n", + " dQ=np.zeros(len(model_coords)),\n", + " intensity=1,\n", + " background=0,\n", + ")\n", "experiment = refl1d.names.Experiment(probe=probe, sample=refl1d_sample)\n", "model_data_no_magnetism_ref1d_raw = experiment.reflectivity()[1]\n", "\n", @@ -253,7 +256,9 @@ " model_coords,\n", " model.unique_name,\n", ")\n", - "plt.plot(model_coords, model_data_no_magnetism_ref1d_easy, 'r-', label=f'EasyReflectometry ({model_interface.name})', linewidth=2)\n", + "plt.plot(\n", + " model_coords, model_data_no_magnetism_ref1d_easy, 'r-', label=f'EasyReflectometry ({model_interface.name})', linewidth=2\n", + ")\n", "\n", "plot_apply_makeup()" ] @@ -290,8 +295,12 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.include_magnetism = True\n", - "model_interface._wrapper.update_layer(list(model_interface._wrapper.storage['layer'].keys())[1], magnetism_rhoM=10, magnetism_thetaM=70)\n", - "model_interface._wrapper.update_layer(list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175)\n", + "model_interface._wrapper.update_layer(\n", + " list(model_interface._wrapper.storage['layer'].keys())[1], magnetism_rhoM=10, magnetism_thetaM=70\n", + ")\n", + "model_interface._wrapper.update_layer(\n", + " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", + ")\n", "model_data_magnetism_layer_1 = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", @@ -327,21 +336,19 @@ "source": [ "# Refl1d model is inverted as compared to EasyReflectometry, so the order of the layers is reversed\n", "refl1d_sample = (\n", - " refl1d_si(0, 0) | \n", - " refl1d_sld_8(150, 0, magnetism=refl1d.names.Magnetism(rhoM=5, thetaM=175)) |\n", - " refl1d_sld_4(100, 0, magnetism=refl1d.names.Magnetism(rhoM=10, thetaM=70)) | \n", - " refl1d_vacuum(0, 0)\n", - ") \n", + " refl1d_si(0, 0)\n", + " | refl1d_sld_8(150, 0, magnetism=refl1d.names.Magnetism(rhoM=5, thetaM=175))\n", + " | refl1d_sld_4(100, 0, magnetism=refl1d.names.Magnetism(rhoM=10, thetaM=70))\n", + " | refl1d_vacuum(0, 0)\n", + ")\n", "model_name = model.unique_name\n", "storage = {'model': {model_name: {}}}\n", "storage['model'][model_name]['scale'] = 10.0\n", "storage['model'][model_name]['bkg'] = 20.0\n", "\n", "polarized_probe = _get_polarized_probe(\n", - " q_array=model_coords,\n", - " dq_array=np.zeros(len(model_coords)),\n", - " model_name=model_name,\n", - " storage=storage)\n", + " q_array=model_coords, dq_array=np.zeros(len(model_coords)), model_name=model_name, storage=storage\n", + ")\n", "\n", "experiment = refl1d.names.Experiment(probe=polarized_probe, sample=refl1d_sample)\n", "model_data_magnetism_ref1d = experiment.reflectivity()[0][1]\n", @@ -352,8 +359,12 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.include_magnetism = True\n", - "model_interface._wrapper.update_layer(list(model_interface._wrapper.storage['layer'].keys())[1], magnetism_rhoM=10, magnetism_thetaM=70)\n", - "model_interface._wrapper.update_layer(list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175)\n", + "model_interface._wrapper.update_layer(\n", + " list(model_interface._wrapper.storage['layer'].keys())[1], magnetism_rhoM=10, magnetism_thetaM=70\n", + ")\n", + "model_interface._wrapper.update_layer(\n", + " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", + ")\n", "model_data_magnetism_easy = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", @@ -406,15 +417,14 @@ "metadata": {}, "outputs": [], "source": [ - "# The magnetism is set to 8. \n", + "# The magnetism is set to 8.\n", "# This would double (pp) and cancel out (mm) the magnitude of the reflectivity oscillations when its angle is set to 90.\n", "# This would give the strongest spin-flipping (pm and mp) when its angle is set to 0.\n", - "# However we set the angle to 45, so the reflectivity oscillations are not doubled or cancelled out, and the spin-flipping is not maximized.\n", + "# However we set the angle to 45, so the reflectivity oscillations are not doubled or cancelled out,\n", + "# and the spin-flipping is not maximized.\n", "refl1d_sample = (\n", - " refl1d_si(0, 0) | \n", - " refl1d_sld_8(150, 0, magnetism=refl1d.names.Magnetism(rhoM=8, thetaM=45)) |\n", - " refl1d_vacuum(0, 0)\n", - ") \n", + " refl1d_si(0, 0) | refl1d_sld_8(150, 0, magnetism=refl1d.names.Magnetism(rhoM=8, thetaM=45)) | refl1d_vacuum(0, 0)\n", + ")\n", "\n", "model_name = model.unique_name\n", "storage = {'model': {model_name: {}}}\n", @@ -422,13 +432,10 @@ "storage['model'][model_name]['bkg'] = 0.0\n", "\n", "polarized_probe = _get_polarized_probe(\n", - " q_array=model_coords,\n", - " dq_array=np.zeros(len(model_coords)),\n", - " model_name=model_name,\n", - " storage=storage,\n", - " all_polarizations=True)\n", + " q_array=model_coords, dq_array=np.zeros(len(model_coords)), model_name=model_name, storage=storage, all_polarizations=True\n", + ")\n", "\n", - "experiment = refl1d.names.Experiment(probe=polarized_probe, sample=refl1d_sample)\n" + "experiment = refl1d.names.Experiment(probe=polarized_probe, sample=refl1d_sample)" ] }, { diff --git a/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort b/docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort similarity index 100% rename from docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort rename to docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort diff --git a/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort b/docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort similarity index 100% rename from docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort rename to docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort diff --git a/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort b/docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort similarity index 100% rename from docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort rename to docs/docs/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort diff --git a/docs/src/tutorials/simulation/resolution_functions.ipynb b/docs/docs/tutorials/simulation/resolution_functions.ipynb similarity index 90% rename from docs/src/tutorials/simulation/resolution_functions.ipynb rename to docs/docs/tutorials/simulation/resolution_functions.ipynb index 4fc42ad2..48a6893a 100644 --- a/docs/src/tutorials/simulation/resolution_functions.ipynb +++ b/docs/docs/tutorials/simulation/resolution_functions.ipynb @@ -24,6 +24,16 @@ "First configure matplotlib to place figures in notebook and import needed modules. Note that the plot function needs installation of `plopp` seperately or installation of `easyreflectometry[dev]`" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "deb2db0a", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, { "cell_type": "code", "execution_count": null, @@ -31,27 +41,24 @@ "metadata": {}, "outputs": [], "source": [ - "%matplotlib inline\n", - "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", - "import scipp as sc\n", - "import refnx\n", "import pooch\n", + "import refnx\n", + "import scipp as sc\n", "\n", "import easyreflectometry\n", - "\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", - "from easyreflectometry.model import Model\n", "from easyreflectometry.model import LinearSpline\n", + "from easyreflectometry.model import Model\n", "from easyreflectometry.model import PercentageFwhm\n", "from easyreflectometry.model import Pointwise\n", + "from easyreflectometry.plot import plot\n", "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", - "from easyreflectometry.sample import Sample\n", - "from easyreflectometry.plot import plot" + "from easyreflectometry.sample import Sample" ] }, { @@ -97,18 +104,18 @@ "source": [ "file_path_0 = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort\",\n", - " known_hash=\"f8a3e7007b83f0de4e2c761134e7d1c55027f0099528bd56f746b50349369f50\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort',\n", + " known_hash='f8a3e7007b83f0de4e2c761134e7d1c55027f0099528bd56f746b50349369f50',\n", ")\n", "file_path_1 = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort\",\n", - " known_hash=\"9d81a512cbe45f923806ad307e476b27535614b2e08a2bf0f4559ab608a34f7a\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort',\n", + " known_hash='9d81a512cbe45f923806ad307e476b27535614b2e08a2bf0f4559ab608a34f7a',\n", ")\n", "file_path_10 = pooch.retrieve(\n", " # URL to one of Pooch's test files\n", - " url=\"https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort\",\n", - " known_hash=\"991395c0b6a91bf60c12d234c645143dcac1cab929944fc4e452020d44b787ad\",\n", + " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort',\n", + " known_hash='991395c0b6a91bf60c12d234c645143dcac1cab929944fc4e452020d44b787ad',\n", ")\n", "dict_reference = {}\n", "dict_reference['0'] = load(file_path_0)\n", @@ -328,7 +335,7 @@ " model.unique_name,\n", " )\n", " plt.plot(model_coords, model_data, 'k-', label=f'Resolution: {key}%')\n", - " plt.plot(reference_coords, reference_data, 'rx', label=f'Reference')\n", + " plt.plot(reference_coords, reference_data, 'rx', label='Reference')\n", " ax = plt.gca()\n", " ax.set_xlim([-0.01, 0.45])\n", " ax.set_ylim([1e-10, 2.5])\n", @@ -377,14 +384,14 @@ " model_coords,\n", " model.unique_name,\n", ")\n", - "plt.plot(model_coords, model_data, 'k-', label=f'Variable', linewidth=5)\n", + "plt.plot(model_coords, model_data, 'k-', label='Variable', linewidth=5)\n", "\n", "model.resolution_function = PercentageFwhm(1.0)\n", "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", - "plt.plot(model_coords, model_data, 'r-', label=f'Percentage')\n", + "plt.plot(model_coords, model_data, 'r-', label='Percentage')\n", "\n", "ax = plt.gca()\n", "ax.set_xlim([-0.01, 0.45])\n", @@ -416,17 +423,17 @@ " model_coords,\n", " model.unique_name,\n", ")\n", - "plt.plot(model_coords, model_data, 'k-', label=f'Variable', linewidth=5)\n", + "plt.plot(model_coords, model_data, 'k-', label='Variable', linewidth=5)\n", "data_points = []\n", - "data_points.append(reference_coords) # Qz\n", - "data_points.append(reference_data) # R\n", - "data_points.append(reference_variances) # sQz\n", + "data_points.append(reference_coords) # Qz\n", + "data_points.append(reference_data) # R\n", + "data_points.append(reference_variances) # sQz\n", "model.resolution_function = Pointwise(q_data_points=data_points)\n", "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", - "plt.plot(model_coords, model_data, 'r-', label=f'Pointwise')\n", + "plt.plot(model_coords, model_data, 'r-', label='Pointwise')\n", "\n", "ax = plt.gca()\n", "ax.set_xlim([-0.01, 0.45])\n", diff --git a/docs/src/tutorials/simulation/two_layers.png b/docs/docs/tutorials/simulation/two_layers.png similarity index 100% rename from docs/src/tutorials/simulation/two_layers.png rename to docs/docs/tutorials/simulation/two_layers.png diff --git a/docs/src/tutorials/simulation/two_layers.svg b/docs/docs/tutorials/simulation/two_layers.svg similarity index 100% rename from docs/src/tutorials/simulation/two_layers.svg rename to docs/docs/tutorials/simulation/two_layers.svg diff --git a/docs/docs/user-guide/index.md b/docs/docs/user-guide/index.md new file mode 100644 index 00000000..fbdec8b4 --- /dev/null +++ b/docs/docs/user-guide/index.md @@ -0,0 +1,211 @@ +--- +icon: material/book-open-variant +--- + +# :material-book-open-variant: User Guide + +This section provides an overview of the **core concepts**, **key +parameters** and **workflow steps** required for using EasyReflectometry +effectively. + +## Glossary + +The following serves to clarify what we mean by the terms we use in this +project. + +### Sample + +A sample is an ideal representation of the full physical setup. This +includes the layer(s) under investigation, the surrounding superphase, +and the subphase. + +### Calculator + +A calculator is the physics engine which calculates the reflectivity +curve from our inputted sample parameters. We rely on third party +software to provide the necessary calculators. Different calculators +might have different capabilities and limitations. + +Currently, EasyReflectometry can offer two different calculation +engines: + +- [**refnx**](https://refnx.readthedocs.io/) +- [**Refl1D**](https://refl1d.readthedocs.io/en/latest/) + +And we are working to add more, in particular +[**BornAgain**](https://www.bornagainproject.org) and +[**GenX**](https://aglavic.github.io/genx/doc/). + +### Model + +A model combines a sample and calculator. The model is also responsible +for including instrumental effects such as background, scale, and +resolution. + +### Assemblies + +Assemblies are collections of layers that are used to represent a +specific physical setup. Examples include: + +- **Multilayer** – A series of layers grouped as a single object +- **RepeatingMultilayer** – A multilayer with a fixed number of repeats +- **SurfactantLayer** – A layer defined by area per molecule and + chemical formula +- **GradientLayer** – A layer with a graded scattering length density + profile + +### Elements + +Elements are the building blocks that are required to construct a +sample. + +**Layers** are basic elements used to represent a single layer of +material with a thickness and a roughness: + +- `Layer` – Standard layer with material, thickness, and roughness +- `LayerAreaPerMolecule` – Layer defined by area per molecule and + chemical formula + +**Materials** are the most basic elements and are used to represent a +material with given physical properties: + +- `Material` – Simple material defined by SLD (real and imaginary) +- `MaterialDensity` – Material defined by mass density and chemical + formula +- `MaterialSolvated` – Material mixed with a solvent in a given ratio +- `MaterialMixture` – Mixture of two materials + +### Fitting + +Fitting helpers and objective functions. The `MultiFitter` supports +several objective modes for handling reflectometry data during fitting, +especially when measured variances are non-positive. + +## Getting Started + +To use EasyReflectometry in a project: + +```python +import easyreflectometry +from easyreflectometry.sample import Material, Layer +from easyreflectometry.model import Model +from easyreflectometry.fitting import MultiFitter +from easyreflectometry.plot import plot + +# Define your Material +material = Material(...) + +# Create a Layer +layer = Layer(material=material, ...) + +# Make a Sample out of the Layer +sample = Sample(layer, ...) + +# Define a Model of the experiment +model = Model( + sample=sample, + scale=1, + background=1e-6, + ... +) + +# Set parameter bounds for fit +... + +# Perform the fit and plot +fitter = MultiFitter(model) +analysed = fitter.fit(data) + +plot(analysed) +``` + +Details of specific usage of EasyReflectometry can be found in the +[Tutorials](../tutorials/index.md). + +## Objective Functions and Non-Positive Variance Handling + +`MultiFitter` supports several objective modes for handling +reflectometry data during fitting, especially when measured variances +are non-positive. + +The default objective is `hybrid`. This uses ordinary weighted least +squares for points with positive variance and applies a Mighell-style +substitution only to points whose variance is non-positive. The older +`legacy_mask` mode drops non-positive-variance points before fitting. +The `mighell` mode applies the Mighell transform to every point. + +### Mighell Objective + +The full `mighell` objective follows the algebraic form of the +$\chi^2_\gamma$ statistic described by Mighell for Poisson-distributed +count data: + +$$ +\chi^2_\gamma = +\sum_i \frac{[n_i + \min(n_i, 1) - m_i]^2}{n_i + 1} +$$ + +where $n_i$ are observed counts and $m_i$ are model values. + +In EasyReflectometry this is implemented as a weighted least-squares +problem. For each observed value $y_i$ the fitted target is shifted to + +$$ +y_{\mathrm{eff},i} = y_i + \min(y_i, 1) +$$ + +and the effective uncertainty is + +$$ +\sigma_i = \sqrt{y_i + 1} +$$ + +so the minimized objective is + +$$ +\sum_i \left(\frac{y_{\mathrm{eff},i} - f_i}{\sigma_i}\right)^2 = +\sum_i \frac{[y_i + \min(y_i, 1) - f_i]^2}{y_i + 1} +$$ + +### Scope and Interpretation + +Mighell's statistic was derived for Poisson-distributed count data. In +reflectometry workflows, the fitted values are usually normalized +reflectivities or intensities rather than raw counts. They may already +have been processed, scaled, background-corrected, or otherwise +transformed before they reach the fitter. + +This distinction matters when interpreting the result. The full +`mighell` objective is not only a reweighting of residuals; it also +changes the fitted target from $y$ to $y + \min(y, 1)$. For values +between zero and one, this can substantially increase the target value. +A fit can therefore have a good Mighell objective value while looking +poorer against the originally plotted reflectivity curve, or while +having a worse classical chi-square. + +For reflectometry data, `hybrid` is generally the recommended +compromise: it preserves ordinary weighted least-squares behavior where +positive variances are available, while still allowing +non-positive-variance points to contribute through the Mighell-style +substitution. + +### Objective Modes + +- **`hybrid`** (default): Use standard weighted least squares for points + with positive variance and apply the Mighell substitution only where + variance is non-positive. +- **`mighell`**: Apply the Mighell transform to all points. The reported + objective chi-square is evaluated in transformed objective space and + should not be interpreted as a classical chi-square against the + original reflectivity values. +- **`legacy_mask`**: Remove non-positive-variance points before fitting + and use standard weighted least squares for the remaining points. +- **`auto`**: Alias for `hybrid`. + +### Fit Metrics + +The fitter exposes both objective-space and classical fit metrics after +fitting. `objective_chi2` and `objective_reduced_chi` describe the +minimized objective value, while `classical_chi2` and +`classical_reduced_chi` describe the fit quality against the original +reflectivity values (with non-positive-variance points excluded). diff --git a/docs/includes/abbreviations.md b/docs/includes/abbreviations.md new file mode 100644 index 00000000..682f16ff --- /dev/null +++ b/docs/includes/abbreviations.md @@ -0,0 +1,15 @@ + + +*[CIF]: Crystallographic Information File. +*[curl]: Command-line tool for transferring data with URLs. +*[GitHub]: A web-based platform for version control and collaboration. +*[Google Colab]: Cloud service that allows you to run Jupyter Notebooks in the cloud. +*[IUCr]: International Union of Crystallography. +*[Jupyter Notebook]: An open-source web application that allows you to create and share documents that contain live code, equations, visualizations, and narrative text. +*[JupyterLab]: Web-based interactive development environment for notebooks, code, and data. +*[pip]: Package installer for Python. +*[PyPI]: The Python Package Index is a repository of software for the Python programming language. +*[Conda]: Conda is a cross-platform, language-agnostic binary package manager. +*[Pixi]: A modern package manager for Windows, macOS, and Linux. + + diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 00000000..f75e4657 --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,217 @@ +# Project information +site_name: EasyReflectometry Library +site_url: https://easyscience.github.io/reflectometry-lib + +# Repository +repo_url: https://github.com/easyscience/reflectometry-lib +edit_uri: edit/develop/docs/ + +# Copyright +copyright: © 2021-2026 EasyReflectometry + +# Sets the theme and theme-specific configuration +theme: + name: material + custom_dir: overrides + features: + #- content.action.edit # Temporary disable edit button (until decided on which branch to use and where to host the notebooks) + #- content.action.view + - content.code.annotate + - content.code.copy # Auto generated button to copy a code block's content + - content.tooltips + - navigation.footer + - navigation.indexes + #- navigation.instant # Instant loading, but it causes issues with rendering equations + #- navigation.sections + - navigation.top # Back-to-top button + - navigation.tracking # Anchor tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + palette: + # Palette toggle for light mode + - media: '(prefers-color-scheme: light)' + scheme: default + primary: custom + toggle: + icon: fontawesome/solid/sun + name: Switch to dark mode + # Palette toggle for dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + primary: custom + toggle: + icon: fontawesome/solid/moon + name: Switch to light mode + font: + text: Mulish + code: Roboto Mono + icon: + edit: material/file-edit-outline + favicon: assets/images/favicon.png + logo_dark_mode: assets/images/logo_dark.svg + logo_light_mode: assets/images/logo_light.svg + +# A set of key-value pairs, where the values can be any valid YAML +# construct, that will be passed to the template +extra: + generator: false # Disable `Made with Material for MkDocs` (bottom left) + social: # Extra icons in the bottom right corner + - icon: easyscience # File: overrides/.icons/easyscience.svg + link: https://easyscience.org + name: EasyScience Framework Webpage + - icon: easyreflectometry # File: overrides/.icons/easyreflectometry.svg + link: https://easyscience.github.io/reflectometry + name: EasyReflectometry Main Webpage + - icon: fontawesome/brands/github # Name as in Font Awesome + link: https://github.com/easyscience/reflectometry-lib + name: EasyReflectometry Library Source Code on GitHub + # Set custom variables to be used in Markdown and HTML files + vars: + ci_branch: !ENV CI_BRANCH + github_repository: !ENV GITHUB_REPOSITORY + release_version: !ENV RELEASE_VERSION + docs_version: !ENV DOCS_VERSION + notebooks_dir: !ENV NOTEBOOKS_DIR + # Renders a version selector in the header + version: + provider: mike + +# Customization to be included by the theme +extra_css: + - assets/stylesheets/extra.css + +extra_javascript: + - assets/javascripts/extra.js + # MathJax for rendering mathematical expressions + - assets/javascripts/mathjax.js # Custom MathJax config to ensure compatibility with mkdocs-jupyter + - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js # Official MathJax CDN + +# A list of extensions beyond the ones that MkDocs uses by default (meta, toc, tables, and fenced_code) +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - pymdownx.arithmatex: # rendering of equations and integrates with MathJax or KaTeX + generic: true + - pymdownx.blocks.caption + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + options: + custom_icons: + - docs/overrides/.icons + - pymdownx.highlight: # whether highlighting should be carried out during build time by Pygments + use_pygments: true + pygments_lang_class: true + - pymdownx.snippets: + auto_append: + - docs/includes/abbreviations.md + - pymdownx.superfences: # whether highlighting should be carried out during build time by Pygments + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: # enables content tabs + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - toc: + toc_depth: 3 + +# A list of plugins (with optional configuration settings) to use when building the site +plugins: + - autorefs + - inline-svg + - markdownextradata # Plugin that injects the mkdocs.yml extra variables into the Markdown template + - mike # Plugin that makes it easy to deploy multiple versions of the docs + - mkdocs-jupyter: + include: ['*.ipynb'] # Default: ['*.py', '*.ipynb'] + execute: false # Do not execute notebooks during build. They are expected to be pre-executed. + allow_errors: false + include_source: true + include_requirejs: true # Required for Plotly + #custom_mathjax_url: 'https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js' # See 'extra_javascript' above + ignore_h1_titles: true # Use titles defined in the nav section below + remove_tag_config: + remove_input_tags: + - hide-in-docs + - mkdocstrings: + handlers: + python: + paths: ['src'] # Change 'src' to your actual sources directory + options: + annotations_path: source + docstring_style: numpy + group_by_category: true + members: true + members_order: source + heading_level: 1 + show_inheritance: true + show_root_heading: true + show_root_full_path: false + show_submodules: true + show_source: true + - search + +# Determines additional directories to watch when running mkdocs serve +watch: + - includes + - overrides + - ../src + +# Exclude files and folders from the global navigation +not_in_nav: | + index.md + +# Format and layout of the global navigation for the site +nav: + - Introduction: + - Introduction: introduction/index.md + - Installation & Setup: + - Installation & Setup: installation-and-setup/index.md + - User Guide: + - User Guide: user-guide/index.md + - Tutorials: + - Tutorials: tutorials/index.md + - Getting Started: + - Creating a Model: tutorials/basic/model.md + - Defining Materials: tutorials/basic/material_library.md + - Defining Layers: tutorials/basic/layer_library.md + - Creating Assemblies: tutorials/basic/assemblies_library.md + - Simulation: + - Bilayer Simulation: tutorials/simulation/bilayer.ipynb + - Magnetism Simulation: tutorials/simulation/magnetism.ipynb + - Resolution Functions: tutorials/simulation/resolution_functions.ipynb + - Fitting: + - Simple Fitting: tutorials/fitting/simple_fitting.ipynb + - Repeating Multilayer Fitting: tutorials/fitting/repeating.ipynb + - Monolayer Fitting: tutorials/fitting/monolayer.ipynb + - Solvated Material Fitting: tutorials/fitting/material_solvated.ipynb + - Advanced Fitting: + - Multi-Contrast Fitting: tutorials/advancedfitting/multi_contrast.ipynb + - API Reference: + - API Reference: api-reference/index.md + - Model: api-reference/model.md + - Sample: api-reference/sample.md + - Project: api-reference/project.md + - Fitting: api-reference/fitting.md + - Assemblies: + - Multilayer: api-reference/assemblies/multilayer.md + - Repeating Multilayer: api-reference/assemblies/repeating_multilayer.md + - Surfactant Layer: api-reference/assemblies/surfactant_layer.md + - Gradient Layer: api-reference/assemblies/gradient_layer.md + - Elements: + - Layers: + - Layer: api-reference/elements/layer.md + - Layer Area Per Molecule: api-reference/elements/layer_area_per_molecule.md + - Materials: + - Material: api-reference/elements/material.md + - Material Density: api-reference/elements/material_density.md + - Material Mixture: api-reference/elements/material_mixture.md + - Material Solvated: api-reference/elements/material_solvated.md + - Data: api-reference/data.md diff --git a/docs/overrides/.icons/app.svg b/docs/overrides/.icons/app.svg new file mode 100644 index 00000000..b4fdd4f3 --- /dev/null +++ b/docs/overrides/.icons/app.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/overrides/.icons/easyreflectometry.svg b/docs/overrides/.icons/easyreflectometry.svg new file mode 100644 index 00000000..8a2e3087 --- /dev/null +++ b/docs/overrides/.icons/easyreflectometry.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + Logo + + + + + \ No newline at end of file diff --git a/docs/overrides/.icons/easyscience.svg b/docs/overrides/.icons/easyscience.svg new file mode 100644 index 00000000..fb514912 --- /dev/null +++ b/docs/overrides/.icons/easyscience.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/overrides/.icons/google-colab.svg b/docs/overrides/.icons/google-colab.svg new file mode 100644 index 00000000..9cd9d1b0 --- /dev/null +++ b/docs/overrides/.icons/google-colab.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 00000000..2e146827 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block content %} + +{% if page.nb_url %} + {# Parse notebook path/URL #} + {% set parts = page.nb_url.split('/') %} + {% set tutorial_name = parts[-2] %} + {% set filename = parts[-1] %} + + {# Colab url #} + {% set base_colab_url = "https://colab.research.google.com/github/" %} + {% set colab_url = + base_colab_url ~ config.extra.vars.github_repository ~ + "/blob/gh-pages/" ~ config.extra.vars.docs_version ~ + "/tutorials/" ~ tutorial_name ~ "/" ~ filename + %} + + {# Download link: relative to the current page #} + {% set file_url = filename %} + + {# Open in Colab (absolute GitHub URL; works anywhere) #} + + {% include ".icons/google-colab.svg" %} + + + {# Download: use a RELATIVE link to the file next to this page #} + + {% include ".icons/material/download.svg" %} + +{% endif %} + +{{ super() }} +{% endblock content %} diff --git a/docs/overrides/partials/logo.html b/docs/overrides/partials/logo.html new file mode 100644 index 00000000..78fa69ca --- /dev/null +++ b/docs/overrides/partials/logo.html @@ -0,0 +1,15 @@ +{% if ( config.theme.logo_light_mode and config.theme.logo_dark_mode ) %} +logo +logo +{% elif config.theme.logo %} +logo +{% else %} {% set icon = config.theme.icon.logo or "material/library" %} {% +include ".icons/" ~ icon ~ ".svg" %} {% endif %} diff --git a/docs/src/conf.py b/docs/src/conf.py index 36235949..127779c9 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -20,9 +20,10 @@ import datetime import os import sys -import toml from pathlib import Path +import toml + import easyreflectometry sys.path.insert(0, os.path.abspath('../src')) @@ -54,7 +55,7 @@ 'sphinx_autodoc_typehints', 'sphinx_copybutton', 'nbsphinx', - 'myst_parser' + 'myst_parser', ] # Add any paths that contain templates here, relative to this directory. @@ -71,8 +72,8 @@ # General information about the project. project = 'EasyReflectometry' -copyright = f"{datetime.date.today().year}, EasyReflectometry" -author = "EasyReflectometry" +copyright = f'{datetime.date.today().year}, EasyReflectometry' +author = 'EasyReflectometry' # The version info for the project you're documenting, acts as replacement # for |version| and |release|, also used in various other places throughout @@ -105,7 +106,7 @@ autoclass_content = 'class' autodoc_member_order = 'bysource' autodoc_typehints = 'signature' -autodoc_class_signature = "separated" +autodoc_class_signature = 'separated' # -- Options for HTML output ------------------------------------------- @@ -116,7 +117,7 @@ html_logo = os.path.join('_static', 'logo.png') html_favicon = os.path.join('_static', 'favicon.ico') html_theme_options = { -# 'logo_only': True, + # 'logo_only': True, 'navigation_with_keys': True } html_baseurl = 'https://docs.easyreflectometry.org' @@ -132,7 +133,7 @@ html_static_path = ['_static'] nbsphinx_execute_arguments = [ - "--Session.metadata=scipp_docs_build=True", + '--Session.metadata=scipp_docs_build=True', ] @@ -148,15 +149,12 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # 'preamble': '', - # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -166,9 +164,7 @@ # (source start file, target name, title, author, documentclass # [howto, manual, or own class]). latex_documents = [ - (master_doc, 'EasyReflectometry.tex', - 'EasyReflectometry Documentation', - 'Andrew R. McCluskey', 'manual'), + (master_doc, 'EasyReflectometry.tex', 'EasyReflectometry Documentation', 'Andrew R. McCluskey', 'manual'), ] @@ -176,11 +172,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'EasyReflectometry', - 'EasyReflectometry Documentation', - [author], 1) -] +man_pages = [(master_doc, 'EasyReflectometry', 'EasyReflectometry Documentation', [author], 1)] # -- Options for Texinfo output ---------------------------------------- @@ -189,11 +181,13 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'EasyReflectometry', - 'EasyReflectometry Documentation', - author, - 'EasyReflectometry', - 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + 'EasyReflectometry', + 'EasyReflectometry Documentation', + author, + 'EasyReflectometry', + 'One line description of project.', + 'Miscellaneous', + ), ] - diff --git a/docs/src/tutorials/advancedfitting/advancedfitting.rst b/docs/src/tutorials/advancedfitting/advancedfitting.rst deleted file mode 100644 index 8c12ba54..00000000 --- a/docs/src/tutorials/advancedfitting/advancedfitting.rst +++ /dev/null @@ -1,9 +0,0 @@ -Advanced Fitting -================ - -These are advanced fitting examples using the :py:mod:`easyreflectometry` library, to get an understanding of the possibilities. - -.. toctree:: - :maxdepth: 1 - - multi_contrast.ipynb \ No newline at end of file diff --git a/docs/src/tutorials/basic/assemblies_library.rst b/docs/src/tutorials/basic/assemblies_library.rst deleted file mode 100644 index d72201a9..00000000 --- a/docs/src/tutorials/basic/assemblies_library.rst +++ /dev/null @@ -1,249 +0,0 @@ -Creating multilayers and surfactant layers -=========================================== - -:py:mod:`easyreflectometry` is designed to be used with a broad range of different assemblies. -Assemblies are collective layers behaving as a single object, for example, a multilayer or a surfactant layer. -These assemblies offer flexibility for the user and enable more powerful analysis by making chemical and physical constraints available with limited code. -In this page, we will document the assemblies that are available with simple examples of the constructors that exist. -Full API documentation is also available for the :py:mod:`easyreflectometry.sample.assemblies` module. - -:py:class:`Multilayer` ----------------------- - -This assembly should be used for a series of layers that should be thought of as a single object. -For example, in the `simple fitting tutorial`_ this assembly type is used to combine the silicon and silicon dioxide layer that as formed into a single object. -All of the separate layers in these objects will be fitted individually, i.e. there is no constraints present, however, there is some cognative benefit to grouping layers together. - -To create a :py:class:`Multilayer` object, we use the following construction. - -.. code-block:: python - - from easyreflectometry.sample import Layer - from easyreflectometry.sample import Material - from easyreflectometry.sample import Multilayer - - si = Material( - sld=2.07, - isld=0, - name='Si' - ) - sio2 = Material( - sld=3.47, - isld=0, - name='SiO2' - ) - si_layer = Layer( - material=si, - thickness=0, - roughness=0, - name='Si layer' - ) - sio2_layer = Layer( - material=sio2, - thickness=30, - roughness=3, - name='SiO2 layer' - ) - - subphase = Multilayer( - layers=[si_layer, sio2_layer], - name='Si/SiO2 subphase' - ) - -This will create a :py:class:`Multilayer` object named :code:`subphase` which we can use in some :py:class:`Structure` for our analysis. - -:py:class:`RepeatingMultilayer` -------------------------------- - -The :py:class:`RepeatingMultilayer` assembly type is an extension of the :py:class:`Multilayer` for the analysis of systems with a multilayer that has some number of repeats. -This assembly type imposes some constraints, specifically that all of the repeats have the exact same structure (i.e. thicknesses, roughnesses, and scattering length densities), -which brings with it some computational saving as the reflectometry coefficients only needs to be calculated once for this structure and propagated for the correct number of repeats. -There is a `tutorial`_ that discusses the utilisation of this assembly type for a nickel-titanium multilayer system. - -The creation of a :py:class:`RepeatingMultilayer` object is very similar to that for the :py:class:`Multilayer`, with the addition of a number of repetitions. - -.. code-block:: python - - from easyreflectometry.sample import Layer - from easyreflectometry.sample import Material - from easyreflectometry.sample import RepeatingMultilayer - - ti = Material( - sld=-1.9493, - isld=0, - name='Ti' - ) - ni = Material( - sld=9.4245, - isld=0, - name='Ni' - ) - ti_layer = Layer( - material=ti, - thickness=40, - roughness=0, - name='Ti Layer' - ) - ni_layer = Layer( - material=ni, - thickness=70, - roughness=0, - name='Ni Layer' - ) - ni_ti = RepeatingMultilayer( - layers=[ti_layer, ni_layer], - repetitions=10, - name='Ni/Ti Multilayer' - ) - -The number of repeats is a parameter that can be varied in the optimisation process, however given this is a value that depends on the synthesis of the sample this is unlikely to be necessary. - -:py:class:`SurfactantLayer` ---------------------------- - -The :py:class:`SurfactantLayer` assembly type allows for the creating of a model to describe a monolayer of surfactant at some interface. -Using this assembly, we can define our surfactant in terms of the chemistry of the head and tail groups and be confident that the constraints are present to ensure the number density if kept constant. -The `surfactant monolayer tutorial`_ looks in detail at the definition of the scattering length density in the :py:class:`SurfactantLayer`. -However, it is founded on the chemical formula for the head and tail group and the area per molecule that these groups occupy. - -The creation of a :py:class:`SurfactantLayer` object is shown below. - -.. code-block:: python - - from easyreflectometry.sample import LayerAreaPerMolecule - from easyreflectometry.sample import Material - from easyreflectometry.sample import SurfactantLayer - - area_per_molecule = 48 - roughness = 3.3 - subphase = Material( - sld=6.36, - isld=0.0, - name='D2O' - ) - superphase = Material( - sld=0.0, - isld=0.0, - name='Air' - ) - tail_layer = LayerAreaPerMolecule( - molecular_formula='C30D64', - thickness=16.0, - solvent=superphase, - solvent_fraction=0.0, - area_per_molecule=area_per_molecule, - roughness=roughness - ) - head_layer = LayerAreaPerMolecule( - molecular_formula='C10H18NO8P', - thickness=10.0, - solvent=subphase, - solvent_fraction=0.2, - area_per_molecule=area_per_molecule, - roughness=roughness - ) - dspc = SurfactantLayer( - tail_layer=tail_layer, - head_layer=head_layer - ) - -On creation, the area per molecule and roughness above both the head and tail layers can be constrained to be the same. -These constraints can be addded by setting :code:`dppc.constrain_area_per_molecule = True` or :code:`dppc.conformal_roughness = True`. -Furthermore, as shown in the `surfactant monolayer tutorial`_ the conformal roughness can be defined by that of the subphase. - -The use of the :py:class:`SurfactantLayer` in multiple contrast data analysis is shown in a `multiple contrast tutorial`_. - -:py:class:`Bilayer` -------------------- - -The :py:class:`Bilayer` assembly type represents a phospholipid bilayer at an interface. -It consists of two surfactant layers where one is inverted, creating the structure: - -.. code-block:: text - - Head₁ - Tail₁ - Tail₂ - Head₂ - -This assembly is particularly useful for studying supported lipid bilayers and membrane systems. -The bilayer comes pre-populated with physically meaningful constraints: - -- Both tail layers share the same structural parameters (thickness, area per molecule) -- Head layers share thickness and area per molecule (different hydration/solvent fraction allowed) -- A single roughness parameter applies to all interfaces (conformal roughness) - -These default constraints can be enabled or disabled as needed for specific analyses. - -The creation of a :py:class:`Bilayer` object is shown below. - -.. code-block:: python - - from easyreflectometry.sample import Bilayer - from easyreflectometry.sample import LayerAreaPerMolecule - from easyreflectometry.sample import Material - - # Create materials for solvents - d2o = Material(sld=6.36, isld=0.0, name='D2O') - air = Material(sld=0.0, isld=0.0, name='Air') - - # Create head layer (used for front, back head will be auto-created with constraints) - head = LayerAreaPerMolecule( - molecular_formula='C10H18NO8P', - thickness=10.0, - solvent=d2o, - solvent_fraction=0.3, - area_per_molecule=48.2, - roughness=3.0, - name='DPPC Head' - ) - - # Create tail layer (both tail positions will share these parameters) - tail = LayerAreaPerMolecule( - molecular_formula='C32D64', - thickness=16.0, - solvent=air, - solvent_fraction=0.0, - area_per_molecule=48.2, - roughness=3.0, - name='DPPC Tail' - ) - - # Create bilayer with default constraints - bilayer = Bilayer( - front_head_layer=head, - tail_layer=tail, - constrain_heads=True, - conformal_roughness=True, - name='DPPC Bilayer' - ) - -The head layers can have different solvent fractions (hydration) even when constrained, -enabling the modeling of asymmetric bilayers at interfaces where the two sides of the -bilayer may have different solvent exposure. - -The constraints can be controlled at runtime: - -.. code-block:: python - - # Disable head constraints to allow different head layer structures - bilayer.constrain_heads = False - - # Disable conformal roughness to allow different roughness values - bilayer.conformal_roughness = False - -Individual layers can be accessed via properties: - -.. code-block:: python - - # Access the four layers - bilayer.front_head_layer # First head layer - bilayer.front_tail_layer # First tail layer - bilayer.back_tail_layer # Second tail layer (constrained to front tail) - bilayer.back_head_layer # Second head layer - -For more detailed examples including simulation and parameter access, see the `bilayer tutorial`_. - - -.. _`simple fitting tutorial`: ../tutorials/simple_fitting.html -.. _`tutorial`: ../tutorials/repeating.html -.. _`surfactant monolayer tutorial`: ../tutorials/monolayer.html -.. _`multiple contrast tutorial`: ../tutorials/multi_contrast.html -.. _`bilayer tutorial`: ../tutorials/simulation/bilayer.html \ No newline at end of file diff --git a/docs/src/tutorials/basic/basic.rst b/docs/src/tutorials/basic/basic.rst deleted file mode 100644 index bcb94f58..00000000 --- a/docs/src/tutorials/basic/basic.rst +++ /dev/null @@ -1,13 +0,0 @@ -Basic -===== - -The :py:mod:`easyreflectometry` package is focused on making easy to use functionality for specific modelling approaches. -In order to achieve this, we have a sample library with different functionality. - -.. toctree:: - :maxdepth: 1 - - model - material_library - layer_library - assemblies_library \ No newline at end of file diff --git a/docs/src/tutorials/basic/layer_library.rst b/docs/src/tutorials/basic/layer_library.rst deleted file mode 100644 index 76c75ad4..00000000 --- a/docs/src/tutorials/basic/layer_library.rst +++ /dev/null @@ -1,84 +0,0 @@ -Defining Layers -=============== - -Similar to a range of different `materials`_, there are a few different ways that a layer can be defined in :py:mod:`easyreflectometry`. - -:py:class:`Layer` ------------------ - -The :py:class:`Layer` is the simplest possible type of layer, taking a :py:class:`Material` and two floats associated with the thickness and upper (that is closer to the source of the incident radiation) roughness. -So we construct a :py:class:`Layer` as follows for a 100 Å thick layer of boron with a roughness of 10 Å. - -.. code-block:: python - - from easyreflectometry.sample import Material - from easyreflectometry.sample import Layer - - boron = Material( - sld=6.908, - isld=-0.278, - name='Boron' - ) - boron_layer = Layer( - material=boron, - thickness=100, - roughness=10, - name='Boron Layer' - ) - -This type of layer is used extensively in the `tutorials`_ - -To create a semi-infinite layer one needs to set the thickness to 0 and the roughness to 0. - -.. code-block:: python - - from easyreflectometry.sample import Material - from easyreflectometry.sample import Layer - - si = Material( - sld=2.07, - isld=0, - name='Si' - ) - semi_infinite_layer = Layer( - material=si, - thickness=0, - roughness=0, - name='Si layer' - ) - -:py:class:`LayerAreaPerMolecule` --------------------------------- - -The :py:class:`LayerAreaPerMolecule` layer type is the fundation of the :py:class:`SurfactantLayer` assemblies type (further information on this can be found in the `assemblies library`_). -The purpose of the :py:class:`LayerAreaPerMolecule` is to allow a layer to be defined in terms of the chemical formula of the material and the area per molecule of the layer. -The area per molecule is a common description of surface density in the surfactant monolayer and bilayer community. - -We can construct a 10 Å thick :py:class:`LayerAreaPerMolecule` of phosphatidylcholine, with an area per molecule of 48 Å squared and a roughness of 3 Å that has 20 % solvent surface coverage with D2O using the following. - -.. code-block:: python - - from easyreflectometry.sample import Material - from easyreflectometry.sample import LayerAreaPerMolecule - - d2o = Material( - sld=6.36, - isld=0, - name='D2O' - ) - molecular_formula = 'C10H18NO8P' - pc = LayerAreaPerMolecule( - molecular_formula=molecular_formula, - thickness=10, - solvent=d2o, - solvent_fraction=.2, - area_per_molecule=48, - roughness=3, - name='PC Layer' - ) - -It is expected that the typical user will not interface directly with the :py:class:`LayerAreaPerMolecule` assembly type, but instead the :py:class:`SurfactantLayer` `assemblies library`_ will be used instead. - -.. _`materials`: ./material_library.html -.. _`tutorials`: ../tutorials/tutorials.html -.. _`assemblies library`: ./assemblies_library.html \ No newline at end of file diff --git a/docs/src/tutorials/basic/material_library.rst b/docs/src/tutorials/basic/material_library.rst deleted file mode 100644 index 2aaf0911..00000000 --- a/docs/src/tutorials/basic/material_library.rst +++ /dev/null @@ -1,87 +0,0 @@ -Defining materials -================== - -In order to support a wide range of applications (and to build complex `assemblies`_) there are a few different types of material that can be utilised in :py:mod:`easyreflectometry`. -These can include constraints or enable the user to define the material based on chemical or physical properties. -Full API documentation for the :py:mod:`easyreflectometry.sample.elements.material` module is also available, but here we will give some simple uses for them. - -:py:class:`Material` --------------------- - -The simplest type of material that is available is the :py:class:`Material`. -This allows the user to define a single type of material, with a real and imaginary component to the scattering length density. -The construction of a :py:class:`Material` is achieved as shown below. - -.. code-block:: python - - from easyreflectometry.sample import Material - - boron = Material( - sld=6.908, - isld=-0.278, - name='Boron' - ) - -The above object will have the properties of :py:attr:`sld` and :py:attr:`isld`, which will have values of :code:`6.908 1/angstrom^2` and :code:`-0.278 1/angstrom^2` respectively. -As is shown in the `tutorials`_, a material can be used to construct a :py:class:`Layer` from which `slab models`_ are created. - -:py:class:`MaterialDensity` ---------------------------- - -In addition to defining a material by its scattering length density, it may be useful to define a material by the mass density and chemical formula. -This is possible with the :py:class:`MaterialDensity` material type, which uses the scattering length and atomic mass from the chemical formula and the density to determine the scattering length density. -It is then possible to vary the density, which defines the scattering length density in turn. -The :py:class:`MaterialDensity` material can be create as follows. - -.. code-block:: python - - from easyreflectometry.sample import MaterialDensity - - chemical_structure = 'SiO2' - si = MaterialDensity( - chemical_structure=chemical_structure, - density=2.65, - name='SiO2 Material' - ) - -The density should be in units of grams per cubic centimeter and the scattering length is calculated from :code:`'SiO2'`. - -:py:class:`MaterialSolvated` ----------------------------- - -Sometimes it is desirable to have a layer that consists of a material and a solvent in some ratio. -An example of this is shown in the `solvation tutorial`_, where a polymer film solvated with D2O is modelled. -To produce a material that is described by such a mixture, there is :py:class:`MaterialSolvated`. -This is constructed from two constituent :py:class:`Materials` and the fractional amount of the material in the solvent. -So to produce a :py:class:`MaterialSolvated` that is 20 % D2O in a polymer, the following is used. - -.. code-block:: python - - from easyreflectometry.sample import Material - from easyreflectometry.sample import MaterialSolvated - - polymer = Material( - sld=2., - isld=0., - name='Polymer' - ) - d2o = Material( - sld=6.36, - isld=0, - name='D2O' - ) - - solvated_polymer = MaterialSolvated( - material=polymer, - solvent=d2o, - solvent_fraction=0.2, - name='Solvated Polymer' - ) - -For the :py:attr:`solvated_polymer` object, the :py:attr:`sld` will be :code:`2.872 1/angstrom^2` (the weighted average of the two scattering length densities). -The :py:class:`MaterialSolvated` includes a constraint such that if the value of either constituent scattering length densities (both real and imaginary components) or the fraction changes, then the resulting material :py:attr:`sld` and :py:attr:`isld` will change appropriately. - -.. _`assemblies`: ./assemblies_library.html -.. _`tutorials`: ../tutorials/tutorials.html -.. _`slab models`: https://www.reflectometry.org/isis_school/3_reflectometry_slab_models/the_slab_model.html -.. _`solvation tutorial`: ../tutorials/solvation.html \ No newline at end of file diff --git a/docs/src/tutorials/basic/model.rst b/docs/src/tutorials/basic/model.rst deleted file mode 100644 index 47134397..00000000 --- a/docs/src/tutorials/basic/model.rst +++ /dev/null @@ -1,80 +0,0 @@ -Creating a model -================ - -The main component of an experiment in :py:mod:`easyreflectometry` is the :py:class:`Model`. -This is a description of the :py:class:`Sample` and the environment in which the experiment is performed. -The :py:class:`Model` is used to calculate the reflectivity of the :py:class:`Sample` at a given set of angles (Q-points). -The :py:func:`resolution_functions` are used to quantify the experimental uncertainties in wavelength and angle, allowing the :py:class:`Model` to accurately describe the data. - -:py:class:`Model` ------------------ - -A :py:class:`Model` instance contains a :py:class:`Sample` and variables describing experimental settings. -To be able to compute reflectivities it is also necessary to have a :py:class:`Calculator` (interface). - -.. code-block:: python - - from easyreflectometry.calculators import CalculatorFactory - from easyreflectometry.model import Model - from easyreflectometry.sample import Sample - - default_sample = Sample() - model = Model( - sample=default_sample, - scale=1.0, - background=1e-6 - ) - - interface = CalculatorFactory() - model.interface = interface - -This will create a :py:class:`Model` instance with the :py:attr:`default_sample` and the environment variables :py:attr:`scale` factor set to 1.0 and a :py:attr:`background` of 1e-6. -Following the :py:attr:`interface` is set to the default calculator that is :py:class:`Refnx`. - - -:py:mod:`resolution_functions` ------------------------------- -A resolution function enables the :py:mod:`easyreflectometry` model to incorporate the experimental uncertainties in wavelength and incident angle into the model. -In its essence the resolution function controls the smearing to apply when determing the reflectivtiy at a given Q-point. -For a given Q-point the smearing to apply is given as a weighted average of the neighboring Q-point, which weigths are by a normal distribution. -This normal distribution is then defined by a Q-point dependent Full Width at the Half Maximum (FWHM) that is given by the resolution function. - -:py:class:`PercentageFwhm` -Often we rely on a resolution function that has a simple functional dependecy of the Q-point. -By this is understood that the applied smearing in an Q-point has a FWHM that is simply a percentage of the value of the Q-point. - -.. code-block:: python - - from easyreflectometry.model import Model - from easyreflectometry.model import PercentageFwhm - - resolution_function = PercentageFwhm(1.1) - - m = Model( - resolution_function=resolution_function - ) - -This will create a :py:class:`Model` instance where the resolution function is defined as 1.1% of the Q-point value, which again is the FWHM for the smearing. - - -:py:func:`LinearSpline` -Alternatively the FWHM value might be determined and declared directly for each measured Q-point. -When this is the case the provided Q-points and the corresponding FWHM values can be used to declare a linear spline function -and thereby enable a determination of the reflectivity at an arbitrary point within the provided range of discrete Q-points. - -.. code-block:: python - - from easyreflectometry.model import Model - from easyreflectometry.model import LinearSpline - - m = Model() - - resolution_function = LinearSpline( - q_data_points=[0.01, 0.2, 0.31], - fwhm_values=[0.001, 0.043, 0.026] - ) - - m.resolution_function = resolution_function - -This will create a :py:class:`Model` instance where the resolution function defining the FWHM is determined from a linear interpolation. -In the present case the provided data Q-points are (`[0.01, 0.2, 0.31]`) and the corresponding FWHM function values are (`[0.001, 0.043, 0.026]`). diff --git a/docs/src/tutorials/extra/extra.rst b/docs/src/tutorials/extra/extra.rst deleted file mode 100644 index 9d68b33a..00000000 --- a/docs/src/tutorials/extra/extra.rst +++ /dev/null @@ -1,7 +0,0 @@ -Extra -===== - -These are extra examples using the :py:mod:`easyreflectometry` library, to get an understanding of the possibilities. - -.. toctree:: - :maxdepth: 1 \ No newline at end of file diff --git a/docs/src/tutorials/fitting/fitting.rst b/docs/src/tutorials/fitting/fitting.rst deleted file mode 100644 index 52b6c14f..00000000 --- a/docs/src/tutorials/fitting/fitting.rst +++ /dev/null @@ -1,12 +0,0 @@ -Fitting -======= - -These are basic fitting examples using the :py:mod:`easyreflectometry` library, to get an understanding of the possibilities. - -.. toctree:: - :maxdepth: 1 - - simple_fitting.ipynb - repeating.ipynb - monolayer.ipynb - material_solvated.ipynb \ No newline at end of file diff --git a/docs/src/tutorials/simulation/simulation.rst b/docs/src/tutorials/simulation/simulation.rst deleted file mode 100644 index 5cf9ced4..00000000 --- a/docs/src/tutorials/simulation/simulation.rst +++ /dev/null @@ -1,11 +0,0 @@ -Simulation -========== - -These are basic simulation examples using the :py:mod:`easyreflectometry` library, to get an understanding of the possibilities. - -.. toctree:: - :maxdepth: 1 - - bilayer.ipynb - magnetism.ipynb - resolution_functions.ipynb \ No newline at end of file diff --git a/docs/src/tutorials/tutorials.rst b/docs/src/tutorials/tutorials.rst deleted file mode 100644 index b73e6666..00000000 --- a/docs/src/tutorials/tutorials.rst +++ /dev/null @@ -1,49 +0,0 @@ -========== -How to use -========== - -Dictionary -========== -The following serves to clarify what we mean by the terms we use in this project. - -Sample ------- -A sample is an ideal representation of a the full physical setup. -This includes the layer(s) under investigation, the surrounding superphase, and the subphase. - -Calculator ----------- -A calculator is the physics engine which calculates the reflectivity curve from our inputted sample parameters. -We rely on third party software to provide the necessary calculators. -Different calculators might have different capabilities and limitations. - -Model ------ -A model combines a sample and calculator. -The model is also responsible for including instrumental effects such as background, scale, and resolution. - - -Calculators & Optimisation -========================== - -:py:mod:`easyreflectometry` is built on the :py:mod:`easyscience` framework which facilities the use of a range of different reflectometry calculation engines and optimiser solutions. -Currently, :py:mod:`easyreflectometry` can offer two different calculation engines, namely: - -* `refnx`_ -* `Refl1D`_ - -And we are working to add more, in particular `bornagain`_ and `GenX`_. - -.. _`refnx`: https://refnx.readthedocs.io/ -.. _`Refl1D`: https://refl1d.readthedocs.io/en/latest/ -.. _`BornAgain`: https://www.bornagainproject.org -.. _`GenX`: https://aglavic.github.io/genx/doc/ - -.. toctree:: - :maxdepth: 2 - - basic/basic - simulation/simulation - fitting/fitting - advancedfitting/advancedfitting - extra/extra diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..1b7139b3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,65 @@ +{ + "name": "reflectometry-lib", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "prettier": "^3.8.3", + "prettier-plugin-toml": "^2.0.6" + } + }, + "node_modules/@taplo/core": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@taplo/core/-/core-0.2.0.tgz", + "integrity": "sha512-r8bl54Zj1In3QLkiW/ex694bVzpPJ9EhwqT9xkcUVODnVUGirdB1JTsmiIv0o1uwqZiwhi8xNnTOQBRQCpizrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@taplo/lib": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@taplo/lib/-/lib-0.5.0.tgz", + "integrity": "sha512-+xIqpQXJco3T+VGaTTwmhxLa51qpkQxCjRwezjFZgr+l21ExlywJFcDfTrNmL6lG6tqb0h8GyJKO3UPGPtSCWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@taplo/core": "^0.2.0" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-toml": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-toml/-/prettier-plugin-toml-2.0.6.tgz", + "integrity": "sha512-12N/wBuHa9jd/KVy9pRP20NMKxQfQLMseQCt66lIbLaPLItvGUcSIryE1eZZMJ7loSws6Ig3M2Elc2EreNh76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@taplo/lib": "^0.5.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + }, + "peerDependencies": { + "prettier": "^3.0.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..80724263 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "prettier": "^3.8.3", + "prettier-plugin-toml": "^2.0.6" + } +} diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 00000000..0399edad --- /dev/null +++ b/pixi.lock @@ -0,0 +1,13299 @@ +version: 6 +environments: + default: + channels: + - url: https://conda.anaconda.org/nodefaults/ + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: ./ + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: ./ + win-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: ./ + py-311-env: + channels: + - url: https://conda.anaconda.org/nodefaults/ + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0b/0615dbedb98f5b32a35a53290fbdc6e22306968109278d7e58df82d7a9f6/numba-0.65.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: ./ + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/4b/d3c79495dee4831b8bebca2790e72cb90f0c5849c940570a7c7e5b70b952/chardet-7.4.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/0b/b9d1911cfefa61399821dfb37f486d83e0f42630a8d12f7194270c417002/llvmlite-0.47.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: ./ + win-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + - pypi: ./ + py-313-env: + channels: + - url: https://conda.anaconda.org/nodefaults/ + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: ./ + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: ./ + win-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: ./ + user: + channels: + - url: https://conda.anaconda.org/nodefaults/ + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cd/f5/038741f5e747a5f6ea3e72487211579d8cbea5eb9827a9cbd61d0108c4bd/sqlalchemy-2.0.49-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + win-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/6b/6c02f55c2ce2f137ccca0986be7dd89bea31d5bee4346b4377fa3b8586df/ncrystal_core-4.4.2-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 + md5: a9f577daf3de00bca7c3c76c0ecbd1de + depends: + - __glibc >=2.17,<3.0.a0 + - libgomp >=7.5.0 + constrains: + - openmp_impl <0.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 28948 + timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 + md5: aaa2a381ccc56eac91d63b6c1240312f + depends: + - cpython + - python-gil + license: MIT + license_family: MIT + purls: [] + size: 8191 + timestamp: 1744137672556 +- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + name: aiohappyeyeballs + version: 2.6.1 + sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.5 + sha256: 3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.5 + sha256: e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.5 + sha256: a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + name: aiohttp + version: 3.13.5 + sha256: 69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl + name: aiohttp + version: 3.13.5 + sha256: d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.5 + sha256: 3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + name: aiosignal + version: 1.4.0 + sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e + requires_dist: + - frozenlist>=1.1.0 + - typing-extensions>=4.2 ; python_full_version < '3.13' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + name: annotated-doc + version: 0.0.4 + sha256: 571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320 + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 + md5: 2934f256a8acfe48f6ebb4fce6cde29c + depends: + - python >=3.9 + - typing-extensions >=4.0.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/annotated-types?source=hash-mapping + size: 18074 + timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + sha256: f09aed24661cd45ba54a43772504f05c0698248734f9ae8cd289d314ac89707e + md5: af2df4b9108808da3dc76710fe50eae2 + depends: + - exceptiongroup >=1.0.2 + - idna >=2.8 + - python >=3.10 + - typing_extensions >=4.5 + - python + constrains: + - trio >=0.32.0 + - uvloop >=0.22.1 + - winloop >=0.2.3 + license: MIT + license_family: MIT + purls: + - pkg:pypi/anyio?source=compressed-mapping + size: 146764 + timestamp: 1774359453364 +- conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf + md5: 54898d0f524c9dee622d44bbb081a8ab + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/appnope?source=hash-mapping + size: 10076 + timestamp: 1733332433806 +- pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + name: arabic-reshaper + version: 3.0.1 + sha256: 41c5adc2420f85758eada7e880251c4b6a2adbd83377bd27e5d4eba71f648bc7 + requires_dist: + - fonttools>=4.0 ; extra == 'with-fonttools' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad + md5: 8ac12aff0860280ee0cff7fa2cf63f3b + depends: + - argon2-cffi-bindings + - python >=3.9 + - typing-extensions + constrains: + - argon2_cffi ==999 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi?source=hash-mapping + size: 18715 + timestamp: 1749017288144 +- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda + sha256: b81f852f13a1d148f6ad7e2a29ab375eb1558b73c9bfa38792d98ea7fb414cff + md5: 6e36e9d2b535c3fbe2e093108df26695 + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=1.0.1 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 35831 + timestamp: 1762509453632 +- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + sha256: ad188ccc06a06c633dc124b09e9e06fb9df4c32ffc38acc96ecc86e506062090 + md5: 27bbec9f2f3a15d32b60ec5734f5b41c + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=1.0.1 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 35943 + timestamp: 1762509452935 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda + sha256: c15fc1aa6184185f1b31670a16b76d59f484d3efa25b467f28d59088cf0085c0 + md5: 501c2a606787bcd55b9ddee776208333 + depends: + - __osx >=11.0 + - cffi >=1.0.1 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 34403 + timestamp: 1762509963182 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + sha256: 05ea6fa7109235cfb4fc24526bae1fe82d88bbb5e697ab3945c313f5f041af5b + md5: e23e087109b2096db4cf9a3985bab329 + depends: + - __osx >=11.0 + - cffi >=1.0.1 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 33947 + timestamp: 1762510144907 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda + sha256: 787e9a5f0a5624fee2af4f58c823bd7933b8ca560e794dd9a821e990b31d2d49 + md5: 5fde0926a521a37d454a5e3162cb6e51 + depends: + - cffi >=1.0.1 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 38502 + timestamp: 1762509668838 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + sha256: 3f8a1affdfeb2be5289d709e365fc6e386d734773895215cf8cbc5100fa6af9a + md5: eabb4b677b54874d7d6ab775fdaa3d27 + depends: + - cffi >=1.0.1 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 38779 + timestamp: 1762509796090 +- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 + md5: 85c4f19f377424eafc4ed7911b291642 + depends: + - python >=3.10 + - python-dateutil >=2.7.0 + - python-tzdata + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/arrow?source=hash-mapping + size: 113854 + timestamp: 1760831179410 +- pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + name: asciichartpy + version: 1.5.25 + sha256: 33c417a3c8ef7d0a11b98eb9ea6dd9b2c1b17559e539b207a17d26d4302d0258 + requires_dist: + - setuptools + - flake8 ; extra == 'qa' +- pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl + name: ase + version: 3.28.0 + sha256: 0e24056302d7307b7247f90de281de15e3031c14cf400bedb1116c3b0d0e50b8 + requires_dist: + - numpy>=1.21.6 + - scipy>=1.8.1 + - matplotlib>=3.5.2 + - sphinx ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinxcontrib-video ; extra == 'docs' + - sphinx-gallery ; extra == 'docs' + - pillow ; extra == 'docs' + - pytest>=7.4.0 ; extra == 'test' + - pytest-xdist>=3.2.0 ; extra == 'test' + - spglib>=1.9 ; extra == 'spglib' + - mypy ; extra == 'lint' + - ruff ; extra == 'lint' + - types-docutils ; extra == 'lint' + - types-pymysql ; extra == 'lint' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + name: asn1crypto + version: 1.5.1 + sha256: db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 +- pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + name: asteval + version: 1.0.8 + sha256: 6c64385c6ff859a474953c124987c7ee8354d781c76509b2c598741c4d1d28e9 + requires_dist: + - build ; extra == 'dev' + - twine ; extra == 'dev' + - sphinx ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - asteval[dev,doc,test] ; extra == 'all' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + sha256: ee4da0f3fe9d59439798ee399ef3e482791e48784873d546e706d0935f9ff010 + md5: 9673a61a297b00016442e022d689faa6 + depends: + - python >=3.10 + constrains: + - astroid >=2,<5 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/asttokens?source=hash-mapping + size: 28797 + timestamp: 1763410017955 +- conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + sha256: ea8486637cfb89dc26dc9559921640cd1d5fd37e5e02c33d85c94572139f2efe + md5: b85e84cb64c762569cc1a760c2327e0a + depends: + - python >=3.10 + - typing_extensions >=4.0.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/async-lru?source=hash-mapping + size: 22949 + timestamp: 1773926359134 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab + md5: c6b0543676ecb1fb2d7643941fe375f2 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/attrs?source=hash-mapping + size: 64927 + timestamp: 1773935801332 +- pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + name: autopep8 + version: 2.3.2 + sha256: ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128 + requires_dist: + - pycodestyle>=2.12.0 + - tomli ; python_full_version < '3.11' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + sha256: a14a9ad02101aab25570543a59c5193043b73dc311a25650134ed9e6cb691770 + md5: f1976ce927373500cc19d3c0b2c85177 + depends: + - python >=3.10 + - python + constrains: + - pytz >=2015.7 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/babel?source=compressed-mapping + size: 7684321 + timestamp: 1772555330347 +- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda + sha256: a23717f9dc06924b988b92ba8dca0f4cb9154cac954457a40adb2f19d57896de + md5: aa8c3009fd8903bebdcb22fbcb4c0dea + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.11.* *_cp311 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 245341 + timestamp: 1777848716685 +- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + sha256: f92ccaef33713bb66d563e8e829dcdb643e1de8c0d29246a999943c68bb8eb6e + md5: cfe95f3eab50bc3dbd4c3a03f2674bd8 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 241034 + timestamp: 1777848719564 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda + sha256: 2e6399a3663e7e20134a208cd09befc44ce1e9efe94d1d36d8911db04f186270 + md5: 3ee7e8ae532366221658b80baee36dc0 + depends: + - python + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 244743 + timestamp: 1777848723707 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + sha256: 257b234caffc760e48c8d7e642d6d0d8bac4341ca19c7df098421358eff636a1 + md5: 84e922fe79295051f6925d7f8d71c98c + depends: + - python + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 242188 + timestamp: 1777848729476 +- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda + sha256: f551f6d7f1a62be18e4165772d300d21e0bd925956bcd9c2a605cabf9a2835d0 + md5: a0b8a2723108680aa6bb85fe3e413e76 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=hash-mapping + size: 243538 + timestamp: 1777848744191 +- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + sha256: b9c1465c03cb6ff79fb4f2feb21955b9b89783f868c900cad45dbcb8d81ab429 + md5: ef16917e1231df5c6f2ba245c8fe35e4 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 240632 + timestamp: 1777848740331 +- pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + name: backrefs + version: '7.0' + sha256: f2c52955d631b9e1ac4cd56209f0a3a946d592b98e7790e77699339ae01c102a + requires_dist: + - regex ; extra == 'extras' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + name: backrefs + version: '7.0' + sha256: a0fa7360c63509e9e077e174ef4e6d3c21c8db94189b9d957289ae6d794b9475 + requires_dist: + - regex ; extra == 'extras' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda + sha256: 978ce415ca2868f8415ce54a9c33fe2d2c9efd6a78dc1a6fe79a4bc3d055fe66 + md5: 28b014780cae10a8435d012ef08c0202 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.11.* *_cp311 + constrains: + - __glibc >=2.17 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 292775 + timestamp: 1762497725251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + sha256: cdf7496797af275f8bb5edd270aa06303dde623c7dd3a5941b0ce085d8f4cdc5 + md5: b59ec3796cba93d0db5f71e361176f27 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.13.* *_cp313 + constrains: + - __glibc >=2.17 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 292710 + timestamp: 1762497710166 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda + sha256: 79594899d1f2472a6d95c3d489268bb9103ba6bab043d9faca379d989074aeb3 + md5: 00ad8eed3ec75b6ec425526968c72e61 + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 268519 + timestamp: 1762497846273 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + sha256: c8e3b95ad2665dc16ac37888fb91dd481fa759bad1fbf799451d12d6bfaec600 + md5: 4b14cba28eaf98170c2ddd7e900efa07 + depends: + - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 267465 + timestamp: 1762497730829 +- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda + sha256: b4cc5ee88f5d19381923519b1f6a1bbc73752f5b1528e4a1df0a3a802e497d13 + md5: fd25556009eae0faab9fc6286150d477 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 170642 + timestamp: 1762497737769 +- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + sha256: 21baf1316a8160fd3b83e7128803735b107f47c58ba5d5305a372fd6c679d42b + md5: 2a664b5cc93fbc9d7ca595b206a299f0 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 170702 + timestamp: 1762497739995 +- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + sha256: bf1e71c3c0a5b024e44ff928225a0874fc3c3356ec1a0b6fe719108e6d1288f6 + md5: 5267bef8efea4127aacd1f4e1f149b6e + depends: + - python >=3.10 + - soupsieve >=1.2 + - typing-extensions + license: MIT + license_family: MIT + purls: + - pkg:pypi/beautifulsoup4?source=hash-mapping + size: 90399 + timestamp: 1764520638652 +- pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + name: bidict + version: 0.23.1 + sha256: 5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5 + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + sha256: f8ff1f98423674278964a46c93a1766f9e91960d44efd91c6c3ed56a33813f46 + md5: 7c5ebdc286220e8021bf55e6384acd67 + depends: + - python >=3.10 + - webencodings + - python + constrains: + - tinycss2 >=1.1.0,<1.5 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/bleach?source=hash-mapping + size: 142008 + timestamp: 1770719370680 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + sha256: 7c07a865e5e4cca233cc4e0eb3f0f5ff6c90776461687b4fb0b1764133e1fd61 + md5: f11a319b9700b203aa14c295858782b6 + depends: + - bleach ==6.3.0 pyhcf101f3_1 + - tinycss2 + license: Apache-2.0 AND MIT + purls: [] + size: 4409 + timestamp: 1770719370682 +- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + name: blinker + version: 1.9.0 + sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda + sha256: c36eb061d9ead85f97644cfb740d485dba9b8823357f35c17851078e95e975c1 + md5: 86daecb8e4ed1042d5dc6efbe0152590 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - libbrotlicommon 1.2.0 hb03c661_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 367573 + timestamp: 1764017405384 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + sha256: dadec2879492adede0a9af0191203f9b023f788c18efd45ecac676d424c458ae + md5: 6c4d3597cf43f3439a51b2b13e29a4ba + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - libbrotlicommon 1.2.0 hb03c661_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 367721 + timestamp: 1764017371123 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda + sha256: 617545ec0e97d35ed2ff7852f2581a20c0dda80b366d0c42a43706687f971ba8 + md5: 150cbf381febcf0a5e470a8d066e1bc0 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 359588 + timestamp: 1764018467340 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + sha256: 2e21dccccd68bedd483300f9ab87a425645f6776e6e578e10e0dd98c946e1be9 + md5: b03732afa9f4f54634d94eb920dfb308 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 359568 + timestamp: 1764018359470 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda + sha256: 1803c838946d79ef6485ae8c7dafc93e28722c5999b059a34118ef758387a4c9 + md5: b0c459f98ac5ea504a9d9df6242f7ee1 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libbrotlicommon 1.2.0 hfd05255_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 335333 + timestamp: 1764018370925 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + sha256: 3558006cd6e836de8dff53cbe5f0b9959f96ea6a6776b4e14f1c524916dd956c + md5: 916a39a0261621b8c33e9db2366dd427 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libbrotlicommon 1.2.0 hfd05255_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 335605 + timestamp: 1764018132514 +- pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + name: build + version: 1.5.0 + sha256: 13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f + requires_dist: + - packaging>=24.0 + - pyproject-hooks + - colorama ; os_name == 'nt' + - importlib-metadata>=4.6 ; python_full_version < '3.10.2' + - tomli>=1.1.0 ; python_full_version < '3.11' + - keyring ; extra == 'keyring' + - uv>=0.1.18 ; extra == 'uv' + - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv' + - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + name: bumps + version: 1.0.4 + sha256: 78b8cfaf9fbcbf2fd77f6d4a2f8c906b0e03a794804ba6caf64d56d6f6cce4d4 + requires_dist: + - numpy + - scipy + - h5py + - dill + - cloudpickle + - matplotlib + - blinker + - aiohttp + - python-socketio + - plotly + - mpld3 + - msgpack + - uncertainties + - build ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - wheel ; extra == 'dev' + - setuptools ; extra == 'dev' + - sphinx ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 260182 + timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 124834 + timestamp: 1771350416561 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + sha256: 6f4ff81534c19e76acf52fcabf4a258088a932b8f1ac56e9a59e98f6051f8e46 + md5: 56fb2c6c73efc627b40c77d14caecfba + depends: + - __win + license: ISC + purls: [] + size: 131388 + timestamp: 1776865633471 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + sha256: c9dbcc8039a52023660d6d1bbf87594a93dd69c6ac5a2a44323af2c92976728d + md5: e18ad67cf881dcadee8b8d9e2f8e5f73 + depends: + - __unix + license: ISC + purls: [] + size: 131039 + timestamp: 1776865545798 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + noarch: python + sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 + md5: 9b347a7ec10940d3f7941ff6c460b551 + depends: + - cached_property >=1.5.2,<1.5.3.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4134 + timestamp: 1615209571450 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + sha256: 6dbf7a5070cc43d90a1e4c2ec0c541c69d8e30a0e25f50ce9f6e4a432e42c5d7 + md5: 576d629e47797577ab0f1b351297ef4a + depends: + - python >=3.6 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cached-property?source=hash-mapping + size: 11065 + timestamp: 1615209567874 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + sha256: 989db6e5957c4b44fa600c68c681ec2f36a55e48f7c7f1c073d5e91caa8cd878 + md5: 929471569c93acefb30282a22060dcd5 + depends: + - python >=3.10 + license: ISC + purls: + - pkg:pypi/certifi?source=compressed-mapping + size: 135656 + timestamp: 1776866680878 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda + sha256: 3ad13377356c86d3a945ae30e9b8c8734300925ef81a3cb0a9db0d755afbe7bb + md5: 3912e4373de46adafd8f1e97e4bd166b + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - pycparser + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 303338 + timestamp: 1761202960110 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + sha256: 2162a91819945c826c6ef5efe379e88b1df0fe9a387eeba23ddcf7ebeacd5bd6 + md5: d0616e7935acab407d1543b28c446f6f + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - pycparser + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 298357 + timestamp: 1761202966461 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda + sha256: 1ffde698463d6e7ed571bdb85cb17bfc1d3a107c026d20047995512dcc2749ec + md5: 4d7f6780e36f18e7601811dddf3bbec5 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 294848 + timestamp: 1761203196617 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + sha256: 1fa69651f5e81c25d48ac42064db825ed1a3e53039629db69f86b952f5ce603c + md5: 050374657d1c7a4f2ea443c0d0cbd9a0 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 291376 + timestamp: 1761203583358 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda + sha256: c9caca6098e3d92b1a269159b759d757518f2c477fbbb5949cb9fee28807c1f1 + md5: f02335db0282d5077df5bc84684f7ff9 + depends: + - pycparser + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 297941 + timestamp: 1761203850323 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + sha256: f867a11f42bb64a09b232e3decf10f8a8fe5194d7e3a216c6bac9f40483bd1c6 + md5: 55b44664f66a2caf584d72196aa98af9 + depends: + - pycparser + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 292681 + timestamp: 1761203203673 +- pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + name: cfgv + version: 3.5.0 + sha256: a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/14/4b/d3c79495dee4831b8bebca2790e72cb90f0c5849c940570a7c7e5b70b952/chardet-7.4.3-cp311-cp311-macosx_11_0_arm64.whl + name: chardet + version: 7.4.3 + sha256: 7005c88da26fd95d8abb8acbe6281d833e9a9181b03cf49b4546c4555389bd97 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + name: chardet + version: 7.4.3 + sha256: e1b98790c284ff813f18f7cf7de5f05ea2435a080030c7f1a8318f3a4f80b131 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + name: chardet + version: 7.4.3 + sha256: 4fbff1907925b0c5a1064cffb5e040cd5e338585c9c552625f30de6bc2f3107a + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl + name: chardet + version: 7.4.3 + sha256: ccc1f83ab4bcfb901cf39e0c4ba6bc6e726fc6264735f10e24ceb5cb47387578 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.4.3 + sha256: bfc134b70c846c21ead8e43ada3ae1a805fff732f6922f8abcf2ff27b8f6493d + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.4.3 + sha256: 4c3da294de1a681097848ab58bd3f2771a674f8039d2d87a5538b28856b815e9 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 + md5: a9167b9571f3baa9d448faa2139d1089 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/charset-normalizer?source=compressed-mapping + size: 58872 + timestamp: 1775127203018 +- pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + name: click + version: 8.3.3 + sha256: a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 + requires_dist: + - colorama ; sys_platform == 'win32' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + name: cloudpickle + version: 3.1.2 + sha256: 9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 + md5: 962b9857ee8e7018c22f2776ffa0b2d7 + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/colorama?source=hash-mapping + size: 27011 + timestamp: 1733218222191 +- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 + md5: 2da13f2b299d8e1995bafbbe9689a2f7 + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/comm?source=hash-mapping + size: 14690 + timestamp: 1753453984907 +- pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + name: contourpy + version: 1.3.3 + sha256: 23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + name: contourpy + version: 1.3.3 + sha256: 1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + name: contourpy + version: 1.3.3 + sha256: d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl + name: contourpy + version: 1.3.3 + sha256: 3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + sha256: 2ceb1f7edb5e5943f7af69e4d6b3339b2e2580e7c9eef76efed4d18d05ae49db + md5: 12baf87bfa62ac066dbe2526f5d89de1 + depends: + - python >=3.10 + - colorama >=0.4.6 + - dunamai >=1.7.0 + - funcy >=1.17 + - jinja2 >=3.1.5 + - jinja2-ansible-filters >=1.3.1 + - packaging >=23.0 + - pathspec >=0.9.0 + - plumbum >=1.6.9 + - prompt-toolkit <3.0.52 + - pydantic >=2.4.2 + - pygments >=2.7.1 + - pyyaml >=5.3.1 + - questionary >=1.8.1 + - eval-type-backport >=0.1.3,<0.3.0 + - platformdirs >=4.3.6 + - typing_extensions >=4.0.0,<5.0.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/copier?source=hash-mapping + size: 58609 + timestamp: 1777562504238 +- pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + name: coverage + version: 7.13.5 + sha256: 941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl + name: coverage + version: 7.13.5 + sha256: 145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + name: coverage + version: 7.13.5 + sha256: 631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: coverage + version: 7.13.5 + sha256: ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: coverage + version: 7.13.5 + sha256: 78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl + name: coverage + version: 7.13.5 + sha256: 258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + noarch: generic + sha256: 836b92c209d4b6b9fb28bd51bd788b22a0c5492ae95eec2724e65a15ed4ab2e1 + md5: 3a8a8b87e72f95b54689fb588e154ec9 + depends: + - python >=3.13,<3.14.0a0 + - python_abi * *_cp313 + license: Python-2.0 + purls: [] + size: 48530 + timestamp: 1775613723457 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda + sha256: 838cde68e70f4e0dc6458613316fa0e50eee5cf86cafb1cee4b7ca1a701a8436 + md5: 96f6e551c7ff30c95c1c8b4d2d1c5c9f + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=2.0 + - libgcc >=14 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - __glibc >=2.17 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=compressed-mapping + size: 1913519 + timestamp: 1777966158377 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + sha256: 7c10cdde9f46d4b990e9c90ffb72bfb672b56d2ecae243d95582c9a9fc417ebf + md5: 2310978ddde7f742d0b7a642d4894388 + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=2.0 + - libgcc >=14 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - __glibc >=2.17 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1916864 + timestamp: 1777966204947 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda + sha256: 6e59412439c8b51ee5f05b3c50b05b43991fa544a895226168fab63be9ba28f9 + md5: cbc7fb4eb2049a4a6cd2c452afd2f7bd + depends: + - __osx >=11.0 + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1855763 + timestamp: 1777966249758 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + sha256: 2adca86f420558eaaad8b8a7ecffadc4a23f980c02716d0fd5bee3f51879e76b + md5: 730fd8d2542ece52b71bc4fbb80ceb10 + depends: + - __osx >=11.0 + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1854514 + timestamp: 1777966313532 +- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda + sha256: a6fca5c54f019724d08fc3d9e54c60ca8c0c8aa8b54571fec3e713bbb64a55c3 + md5: 27def055167d830e4ce6c6821eaee591 + depends: + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1645132 + timestamp: 1777966325193 +- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + sha256: 1fbf66094059379d72f06d3cbb9df5277352a95d25a68d55d1dd60fa6acca5c6 + md5: c216777102e0b49ed307e181df3903d2 + depends: + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1646298 + timestamp: 1777966340031 +- pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl + name: crysfml + version: 0.6.2 + sha256: 0010858646240f6c64e2711c33ccfffd94ee6602859babd1186785e28d6c5c11 + requires_dist: + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: crysfml + version: 0.6.2 + sha256: 734e2180b2c427e77cc9cf9cee4a3651ad563adab28dfe79051f004489f8546c + requires_dist: + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl + name: crysfml + version: 0.6.2 + sha256: b32ddbf4010ce61a535182d58c12c410ed4a0f5de2259e7ef605e7fbcce40be3 + requires_dist: + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl + name: cryspy + version: 0.11.0 + sha256: 0b650655a0fbdc3cfcb28826c2ab9fbc5f491e32e1ea9a47d9b75976cd43f26f + requires_dist: + - numpy + - scipy + - pycifstar + - matplotlib +- pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + name: cssselect2 + version: 0.9.0 + sha256: 6a99e5f91f9a016a304dd929b0966ca464bcfda15177b6fb4a118fc0fb5d9563 + requires_dist: + - tinycss2 + - webencodings + - sphinx ; extra == 'doc' + - furo ; extra == 'doc' + - pytest ; extra == 'test' + - ruff ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + name: cyclebane + version: 24.10.0 + sha256: 902dd318667e4a222afc270cc5bc72c67d5d6047d2e0e1c36018885fb80f5e5d + requires_dist: + - networkx + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + name: cycler + version: 0.12.1 + sha256: 85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 + requires_dist: + - ipython ; extra == 'docs' + - matplotlib ; extra == 'docs' + - numpydoc ; extra == 'docs' + - sphinx ; extra == 'docs' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl + name: darkdetect + version: 0.8.0 + sha256: a7509ccf517eaad92b31c214f593dbcf138ea8a43b2935406bbd565e15527a85 + requires_dist: + - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'macos-listener' + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + name: dask + version: 2026.3.0 + sha256: be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d + requires_dist: + - click>=8.1 + - cloudpickle>=3.0.0 + - fsspec>=2021.9.0 + - packaging>=20.0 + - partd>=1.4.0 + - pyyaml>=5.3.1 + - toolz>=0.12.0 + - importlib-metadata>=4.13.0 ; python_full_version < '3.12' + - numpy>=1.24 ; extra == 'array' + - dask[array] ; extra == 'dataframe' + - pandas>=2.0 ; extra == 'dataframe' + - pyarrow>=16.0 ; extra == 'dataframe' + - distributed>=2026.3.0,<2026.3.1 ; extra == 'distributed' + - bokeh>=3.1.0 ; extra == 'diagnostics' + - jinja2>=2.10.3 ; extra == 'diagnostics' + - dask[array,dataframe,diagnostics,distributed] ; extra == 'complete' + - pyarrow>=16.0 ; extra == 'complete' + - lz4>=4.3.2 ; extra == 'complete' + - pandas[test] ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - pre-commit ; extra == 'test' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda + sha256: e69be2be543c4d4898895d8aebe758bc683c5a1198583ad676f5719782a07131 + md5: 400e4667a12884216df869cad5fb004b + depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2733654 + timestamp: 1769744984842 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + sha256: 8d76d4eeb5a8e3c5666880b465593fdf4a44f47fbbe89ff5b8f9abbe43026326 + md5: e94dbbec2589f3b1d821f43a4bf2ab45 + depends: + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2872698 + timestamp: 1769744980407 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda + sha256: 093b015e9abf27fb4d3b4f7e52417d35cd69a99fab8b95ec5c6c3983275c46ba + md5: 150c921424bc9f08c0378f8a6ae58d05 + depends: + - python + - __osx >=11.0 + - libcxx >=19 + - python 3.11.* *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2668163 + timestamp: 1769745020016 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + sha256: 372464b345220758769f49e76d125933008abec7048df4077a851adcc79da1e8 + md5: b3a832c19cfa5dfcce7575750ef693ed + depends: + - python + - libcxx >=19 + - python 3.13.* *_cp313 + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2761021 + timestamp: 1769744996428 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda + sha256: 661e5c582b1f853a46a78d4bb6e55f2bfdac66e68d015e111f1580a11c28abbf + md5: 683be2cd10e80a367790b3083ce529b7 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 3940002 + timestamp: 1769745017274 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + sha256: f6fe9cbd9e3d3c09f173eeb43676a58bc6169e97da0d190e0201e40828a3a62b + md5: 75eb3091b05924429a3a8d2a9bbdfac2 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 4003589 + timestamp: 1769745018248 +- conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 + md5: 9ce473d1d1be1cc3810856a48b3fab32 + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/decorator?source=hash-mapping + size: 14129 + timestamp: 1740385067843 +- conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + md5: 961b3a227b437d82ad7054484cfa71b2 + depends: + - python >=3.6 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/defusedxml?source=hash-mapping + size: 24062 + timestamp: 1615232388757 +- pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + name: dfo-ls + version: 1.6.5 + sha256: d147d42e471e240f9abf8bc38351a88f555ea6a8fcfd83119bbbf93c36f75ab2 + requires_dist: + - setuptools + - numpy + - scipy>=1.11 + - pandas + - pytest ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-rtd-theme ; extra == 'dev' + - trustregion>=1.1 ; extra == 'trustregion' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl + name: diffpy-pdffit2 + version: 1.6.0 + sha256: f1bba407eac8ff8ef1264ad5a1d3dff840e2d0a5f71e9fb0c0b9b06d5a8eb139 + requires_dist: + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz + name: diffpy-pdffit2 + version: 1.6.0 + sha256: 11a65466f8790f5ac7ae45f2f3fc0d5d116d156d274bcfc079df653123d080e2 + requires_dist: + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl + name: diffpy-pdffit2 + version: 1.6.0 + sha256: 8837088196ddabd688deb77740c3f03ddc33f0df6964a8e3507701c32b67b8b2 + requires_dist: + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl + name: diffpy-structure + version: 3.4.0 + sha256: bd0f06a96635d80316f51ebc0a08003bdeb2cb48c9bb18cbed1455ac60645e48 + requires_dist: + - numpy + - pycifrw + - diffpy-utils + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + name: diffpy-utils + version: 3.7.2 + sha256: 6100600736791a8e4638e3dd476704f4dabe3cab75bcb5c60c83c16a2032519a + requires_dist: + - numpy + - xraydb + - scipy + requires_python: '>=3.10,<3.15' +- pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + name: dill + version: 0.4.1 + sha256: 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d + requires_dist: + - objgraph>=1.7.2 ; extra == 'graph' + - gprof2dot>=2022.7.29 ; extra == 'profile' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + name: distlib + version: 0.4.0 + sha256: 9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 +- pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + name: dnspython + version: 2.8.0 + sha256: 01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af + requires_dist: + - black>=25.1.0 ; extra == 'dev' + - coverage>=7.0 ; extra == 'dev' + - flake8>=7 ; extra == 'dev' + - hypercorn>=0.17.0 ; extra == 'dev' + - mypy>=1.17 ; extra == 'dev' + - pylint>=3 ; extra == 'dev' + - pytest-cov>=6.2.0 ; extra == 'dev' + - pytest>=8.4 ; extra == 'dev' + - quart-trio>=0.12.0 ; extra == 'dev' + - sphinx-rtd-theme>=3.0.0 ; extra == 'dev' + - sphinx>=8.2.0 ; extra == 'dev' + - twine>=6.1.0 ; extra == 'dev' + - wheel>=0.45.0 ; extra == 'dev' + - cryptography>=45 ; extra == 'dnssec' + - h2>=4.2.0 ; extra == 'doh' + - httpcore>=1.0.0 ; extra == 'doh' + - httpx>=0.28.0 ; extra == 'doh' + - aioquic>=1.2.0 ; extra == 'doq' + - idna>=3.10 ; extra == 'idna' + - trio>=0.30 ; extra == 'trio' + - wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + name: docstring-parser-fork + version: 0.0.14 + sha256: 4c544f234ef2cc2749a3df32b70c437d77888b1099143a1ad5454452c574b9af + requires_dist: + - docstring-parser[docs] ; extra == 'dev' + - docstring-parser[test] ; extra == 'dev' + - pre-commit>=2.16.0 ; python_full_version >= '3.9' and extra == 'dev' + - pydoctor>=25.4.0 ; extra == 'docs' + - pytest ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + name: docstripy + version: 0.7.2 + sha256: c4ba35de6c1b1c51f7afad4a46d8953aad55dce1a490d198f7e98c8c63efefda + requires_dist: + - nbformat + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + sha256: 930f21584babebdabc8310f894557d032211f6cb427f7028c7c92cab6fe6cc1f + md5: dbb824a3a87ac1e2ce02f8227be67e74 + depends: + - importlib-metadata >=1.6.0 + - packaging >=20.9 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/dunamai?source=hash-mapping + size: 30866 + timestamp: 1775597880526 +- pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl + name: easydiffraction + version: 0.16.0 + sha256: 2691a1e175974ca79e0ec3c219d92b77f277c38fb3b0b8d25f6f7e99696bf70f + requires_dist: + - asciichartpy + - asteval + - bumps + - colorama + - crysfml + - cryspy + - darkdetect + - dfo-ls + - diffpy-pdffit2 + - diffpy-utils + - essdiffraction + - gemmi + - lmfit + - numpy + - pandas + - plotly + - pooch + - py3dmol + - rich + - scipy + - sympy + - tabulate + - typeguard + - typer + - uncertainties + - varname + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.12' +- pypi: ./ + name: easyreflectometry + version: 1.5.0+devdirty9 + sha256: 6cb81566f4ddb1401f1f6cfdac62844e904c9e177f74d0526912a44ae0489a16 + requires_dist: + - bumps + - easyscience + - orsopy + - pooch + - refl1d>=1.0.0 + - refnx + - scipp + - svglib<1.6 ; sys_platform == 'darwin' or sys_platform == 'linux' + - xhtml2pdf + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - plopp ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.11' + editable: true +- pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl + name: easyscience + version: 2.3.1 + sha256: 51dd343ff4bcf7c36e8fada32ed3ca2bdc7e1226ae08965a2c11d9fd936e3e40 + requires_dist: + - asteval + - bumps + - dfo-ls + - ipykernel + - ipympl + - ipython + - ipywidgets + - jupyterlab + - lmfit + - matplotlib + - numpy + - pixi-kernel + - pooch + - scipp + - uncertainties + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docformatter ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + name: email-validator + version: 2.3.0 + sha256: 80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4 + requires_dist: + - dnspython>=2.0.0 + - idna>=2.0.0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl + name: essdiffraction + version: 26.5.1 + sha256: 8a6c779078c71be250714619214069221ab7968a69580d4e4d3f4b3e9a1a53ad + requires_dist: + - dask>=2022.1.0 + - essreduce>=26.4.0 + - graphviz + - numpy>=2 + - plopp>=26.2.0 + - pythreejs>=2.4.1 + - sciline>=25.4.1 + - scipp>=25.11.0 + - scippneutron>=26.3.0 + - scippnexus>=23.12.0 + - tof>=25.12.0 + - ncrystal[cif]>=4.1.0 + - spglib!=2.7 + - pandas>=2.1.2 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - ipywidgets>=8.1.7 ; extra == 'test' + - autodoc-pydantic ; extra == 'docs' + - ipykernel ; extra == 'docs' + - ipympl ; extra == 'docs' + - ipython!=8.7.0 ; extra == 'docs' + - myst-parser ; extra == 'docs' + - nbsphinx ; extra == 'docs' + - pandas ; extra == 'docs' + - pooch ; extra == 'docs' + - pydata-sphinx-theme>=0.14 ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-design ; extra == 'docs' + - sphinxcontrib-bibtex ; extra == 'docs' + - pyarrow ; extra == 'docs' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + name: essreduce + version: 26.4.1 + sha256: 1758a18fffca9c7c2a6fa9547cf87bf45f9d52fc3ccbdffcf7524f71bc060424 + requires_dist: + - sciline>=25.11.0 + - scipp>=26.3.1 + - scippneutron>=25.11.1 + - scippnexus>=25.6.0 + - graphviz>=0.20 ; extra == 'test' + - ipywidgets>=8.1 ; extra == 'test' + - matplotlib>=3.10.7 ; extra == 'test' + - numba>=0.63 ; extra == 'test' + - pooch>=1.9.0 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - scipy>=1.14 ; extra == 'test' + - tof>=25.12.0 ; extra == 'test' + - autodoc-pydantic ; extra == 'docs' + - graphviz>=0.20 ; extra == 'docs' + - ipykernel ; extra == 'docs' + - ipython!=8.7.0 ; extra == 'docs' + - ipywidgets>=8.1 ; extra == 'docs' + - myst-parser ; extra == 'docs' + - nbsphinx ; extra == 'docs' + - numba>=0.63 ; extra == 'docs' + - plopp ; extra == 'docs' + - pydata-sphinx-theme>=0.14 ; extra == 'docs' + - sphinx>=7 ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-design ; extra == 'docs' + - tof>=25.12.0 ; extra == 'docs' + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + sha256: 05ffdcb83903c159bfbb78a07fbcce6fd6dda41df9c55ed75e0eb1db5528048f + md5: 879479fda1dddb002fdc4885cea33740 + depends: + - eval_type_backport >=0.2.2,<0.2.3.0a0 + - python >=3.9 + license: MIT + license_family: MIT + purls: [] + size: 6662 + timestamp: 1734857849281 +- conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + sha256: 2d721421a60676216e10837a240c75e2190e093920a4016a469fa9a62c95ab5f + md5: 8681d7f876da5e66a1c7fce424509383 + depends: + - python >=3.9 + constrains: + - eval-type-backport >=0.2.2,<0.2.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/eval-type-backport?source=hash-mapping + size: 11520 + timestamp: 1734857840035 +- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 + md5: 8e662bd460bda79b1ea39194e3c4c9ab + depends: + - python >=3.10 + - typing_extensions >=4.6.0 + license: MIT and PSF-2.0 + purls: + - pkg:pypi/exceptiongroup?source=hash-mapping + size: 21333 + timestamp: 1763918099466 +- pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + name: execnet + version: 2.1.2 + sha256: 67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec + requires_dist: + - hatch ; extra == 'testing' + - pre-commit ; extra == 'testing' + - pytest ; extra == 'testing' + - tox ; extra == 'testing' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad + md5: ff9efb7f7469aed3c4a8106ffa29593c + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/executing?source=hash-mapping + size: 30753 + timestamp: 1756729456476 +- pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + name: filelock + version: 3.29.0 + sha256: 96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + name: fonttools + version: 4.62.1 + sha256: 7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + name: fonttools + version: 4.62.1 + sha256: c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl + name: fonttools + version: 4.62.1 + sha256: 40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: fonttools + version: 4.62.1 + sha256: 1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl + name: fonttools + version: 4.62.1 + sha256: e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: fonttools + version: 4.62.1 + sha256: 6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + name: format-docstring + version: 0.2.7 + sha256: c9d50eafebe0f260e3270ca662ff3a0ed4050f64d95e352f8c5f88d9aede42d6 + requires_dist: + - click>=8.0 + - jupyter-notebook-parser>=0.1.4 + - tomli>=1.1.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 + md5: d3549fd50d450b6d9e7dddff25dd2110 + depends: + - cached-property >=1.3.0 + - python >=3.9,<4 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/fqdn?source=hash-mapping + size: 16705 + timestamp: 1733327494780 +- pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + name: freetype-py + version: 2.5.1 + sha256: 0b7f8e0342779f65ca13ef8bc103938366fecade23e6bb37cb671c2b8ad7f124 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + name: frozenlist + version: 1.8.0 + sha256: ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: 2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + name: frozenlist + version: 1.8.0 + sha256: 878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + name: fsspec + version: 2026.4.0 + sha256: 11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 + requires_dist: + - adlfs ; extra == 'abfs' + - adlfs ; extra == 'adl' + - pyarrow>=1 ; extra == 'arrow' + - dask ; extra == 'dask' + - distributed ; extra == 'dask' + - pre-commit ; extra == 'dev' + - ruff>=0.5 ; extra == 'dev' + - numpydoc ; extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - yarl ; extra == 'doc' + - dropbox ; extra == 'dropbox' + - dropboxdrivefs ; extra == 'dropbox' + - requests ; extra == 'dropbox' + - adlfs ; extra == 'full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' + - dask ; extra == 'full' + - distributed ; extra == 'full' + - dropbox ; extra == 'full' + - dropboxdrivefs ; extra == 'full' + - fusepy ; extra == 'full' + - gcsfs>2024.2.0 ; extra == 'full' + - libarchive-c ; extra == 'full' + - ocifs ; extra == 'full' + - panel ; extra == 'full' + - paramiko ; extra == 'full' + - pyarrow>=1 ; extra == 'full' + - pygit2 ; extra == 'full' + - requests ; extra == 'full' + - s3fs>2024.2.0 ; extra == 'full' + - smbprotocol ; extra == 'full' + - tqdm ; extra == 'full' + - fusepy ; extra == 'fuse' + - gcsfs>2024.2.0 ; extra == 'gcs' + - pygit2 ; extra == 'git' + - requests ; extra == 'github' + - gcsfs ; extra == 'gs' + - panel ; extra == 'gui' + - pyarrow>=1 ; extra == 'hdfs' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' + - libarchive-c ; extra == 'libarchive' + - ocifs ; extra == 'oci' + - s3fs>2024.2.0 ; extra == 's3' + - paramiko ; extra == 'sftp' + - smbprotocol ; extra == 'smb' + - paramiko ; extra == 'ssh' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' + - numpy ; extra == 'test' + - pytest ; extra == 'test' + - pytest-asyncio!=0.22.0 ; extra == 'test' + - pytest-benchmark ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-recording ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - requests ; extra == 'test' + - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' + - dask[dataframe,test] ; extra == 'test-downstream' + - moto[server]>4,<5 ; extra == 'test-downstream' + - pytest-timeout ; extra == 'test-downstream' + - xarray ; extra == 'test-downstream' + - adlfs ; extra == 'test-full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' + - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' + - cloudpickle ; extra == 'test-full' + - dask ; extra == 'test-full' + - distributed ; extra == 'test-full' + - dropbox ; extra == 'test-full' + - dropboxdrivefs ; extra == 'test-full' + - fastparquet ; extra == 'test-full' + - fusepy ; extra == 'test-full' + - gcsfs ; extra == 'test-full' + - jinja2 ; extra == 'test-full' + - kerchunk ; extra == 'test-full' + - libarchive-c ; extra == 'test-full' + - lz4 ; extra == 'test-full' + - notebook ; extra == 'test-full' + - numpy ; extra == 'test-full' + - ocifs ; extra == 'test-full' + - pandas<3.0.0 ; extra == 'test-full' + - panel ; extra == 'test-full' + - paramiko ; extra == 'test-full' + - pyarrow ; extra == 'test-full' + - pyarrow>=1 ; extra == 'test-full' + - pyftpdlib ; extra == 'test-full' + - pygit2 ; extra == 'test-full' + - pytest ; extra == 'test-full' + - pytest-asyncio!=0.22.0 ; extra == 'test-full' + - pytest-benchmark ; extra == 'test-full' + - pytest-cov ; extra == 'test-full' + - pytest-mock ; extra == 'test-full' + - pytest-recording ; extra == 'test-full' + - pytest-rerunfailures ; extra == 'test-full' + - python-snappy ; extra == 'test-full' + - requests ; extra == 'test-full' + - smbprotocol ; extra == 'test-full' + - tqdm ; extra == 'test-full' + - urllib3 ; extra == 'test-full' + - zarr ; extra == 'test-full' + - zstandard ; python_full_version < '3.14' and extra == 'test-full' + - tqdm ; extra == 'tqdm' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + sha256: 4a3e3e86b7b49aaa2a0faa57da2bcf39f7ee858499e8335132f83bfeed79191e + md5: 84f8955e99a8944fdee49da39edb0add + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/funcy?source=hash-mapping + size: 30249 + timestamp: 1734381235500 +- pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: gemmi + version: 0.7.5 + sha256: 750b4d9751aaf1460ac4f0f45308ddced25f47bcf7a30355eb3b1f779f03952a + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl + name: gemmi + version: 0.7.5 + sha256: c7d8b08c33fe6ba375223306149092440c69cbfbd55c3d3e3436e5fb315a225d + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl + name: gemmi + version: 0.7.5 + sha256: ad1f72ffa24adbfaf259e11471f6f071a668667f6ca846051f3bfea024fd337d + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + name: ghp-import + version: 2.1.0 + sha256: 8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 + requires_dist: + - python-dateutil>=2.8.1 + - twine ; extra == 'dev' + - markdown ; extra == 'dev' + - flake8 ; extra == 'dev' + - wheel ; extra == 'dev' +- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + name: gitdb + version: 4.0.12 + sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + requires_dist: + - smmap>=3.0.1,<6 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + name: gitpython + version: 3.1.50 + sha256: d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 + requires_dist: + - gitdb>=4.0.1,<5 + - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' + - coverage[toml] ; extra == 'test' + - ddt>=1.1.1,!=1.4.3 ; extra == 'test' + - mock ; python_full_version < '3.8' and extra == 'test' + - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' + - pre-commit ; extra == 'test' + - pytest>=7.3.1 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-instafail ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-sugar ; extra == 'test' + - typing-extensions ; python_full_version < '3.11' and extra == 'test' + - sphinx>=7.4.7,<8 ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + name: graphviz + version: '0.21' + sha256: 54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42 + requires_dist: + - build ; extra == 'dev' + - wheel ; extra == 'dev' + - twine ; extra == 'dev' + - flake8 ; extra == 'dev' + - flake8-pyproject ; extra == 'dev' + - pep8-naming ; extra == 'dev' + - tox>=3 ; extra == 'dev' + - pytest>=7,<8.1 ; extra == 'test' + - pytest-mock>=3 ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - sphinx>=5,<7 ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinx-rtd-theme>=0.2.5 ; extra == 'docs' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: greenlet + version: 3.5.0 + sha256: 2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl + name: greenlet + version: 3.5.0 + sha256: 728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + name: griffelib + version: 2.0.2 + sha256: 925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1 + requires_dist: + - pip>=24.0 ; extra == 'pypi' + - platformdirs>=4.2 ; extra == 'pypi' + - wheel>=0.42 ; extra == 'pypi' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb + md5: b8993c19b0c32a2f7b66cbb58ca27069 + depends: + - python >=3.10 + - typing_extensions + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/h11?source=compressed-mapping + size: 39069 + timestamp: 1767729720872 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 + md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 + depends: + - python >=3.10 + - hyperframe >=6.1,<7 + - hpack >=4.1,<5 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/h2?source=hash-mapping + size: 95967 + timestamp: 1756364871835 +- pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl + name: h5py + version: 3.16.0 + sha256: fb1720028d99040792bb2fb31facb8da44a6f29df7697e0b84f0d79aff2e9bd3 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + name: h5py + version: 3.16.0 + sha256: 42108e93326c50c2810025aade9eac9d6827524cdccc7d4b75a546e5ab308edb + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + name: h5py + version: 3.16.0 + sha256: 9300ad32dea9dfc5171f94d5f6948e159ed93e4701280b0f508773b3f582f402 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl + name: h5py + version: 3.16.0 + sha256: c3f0a0e136f2e95dd0b67146abb6668af4f1a69c81ef8651a2d316e8e01de447 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + name: h5py + version: 3.16.0 + sha256: 18f2bbcd545e6991412253b98727374c356d67caa920e68dc79eab36bf5fedad + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl + name: h5py + version: 3.16.0 + sha256: 17d1f1630f92ad74494a9a7392ab25982ce2b469fc62da6074c0ce48366a2999 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba + md5: 0a802cb9888dd14eeefc611f05c40b6e + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hpack?source=hash-mapping + size: 30731 + timestamp: 1737618390337 +- pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + name: html5lib + version: '1.1' + sha256: 0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d + requires_dist: + - six>=1.9 + - webencodings + - genshi ; extra == 'all' + - chardet>=2.2 ; extra == 'all' + - lxml ; platform_python_implementation == 'CPython' and extra == 'all' + - chardet>=2.2 ; extra == 'chardet' + - genshi ; extra == 'genshi' + - lxml ; platform_python_implementation == 'CPython' and extra == 'lxml' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b + md5: 4f14640d58e2cc0aa0819d9d8ba125bb + depends: + - python >=3.9 + - h11 >=0.16 + - h2 >=3,<5 + - sniffio 1.* + - anyio >=4.0,<5.0 + - certifi + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/httpcore?source=hash-mapping + size: 49483 + timestamp: 1745602916758 +- conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 + md5: d6989ead454181f4f9bc987d3dc4e285 + depends: + - anyio + - certifi + - httpcore 1.* + - idna + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/httpx?source=hash-mapping + size: 63082 + timestamp: 1733663449209 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 + md5: 8e6923fc12f1fe8f8c4e5c9f343256ac + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hyperframe?source=hash-mapping + size: 17397 + timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a + md5: c80d8a3b84358cb967fa81e7075fbc8a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 12723451 + timestamp: 1773822285671 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5 + md5: f1182c91c0de31a7abd40cedf6a5ebef + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 12361647 + timestamp: 1773822915649 +- pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + name: identify + version: 2.6.19 + sha256: 20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a + requires_dist: + - ukkonen ; extra == 'license' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + sha256: 9ab620e6f64bb67737bd7bc1ad6f480770124e304c6710617aba7fe60b089f48 + md5: fb7130c190f9b4ec91219840a05ba3ac + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/idna?source=compressed-mapping + size: 59038 + timestamp: 1776947141407 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 + md5: 080594bf4493e6bae2607e65390c520a + depends: + - python >=3.10 + - zipp >=3.20 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/importlib-metadata?source=compressed-mapping + size: 34387 + timestamp: 1773931568510 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + sha256: a563a51aa522998172838e867e6dedcf630bc45796e8612f5a1f6d73e9c8125a + md5: 0ba6225c279baf7ea9473a62ea0ec9ae + depends: + - python >=3.10 + - zipp >=3.1.0 + constrains: + - importlib-resources >=7.1.0,<7.1.1.0a0 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/importlib-resources?source=compressed-mapping + size: 34809 + timestamp: 1776068839274 +- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + name: iniconfig + version: 2.3.0 + sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + name: interrogate + version: 1.7.0 + sha256: b13ff4dd8403369670e2efe684066de9fcb868ad9d7f2b4095d8112142dc9d12 + requires_dist: + - attrs + - click>=7.1 + - colorama + - py + - tabulate + - tomli ; python_full_version < '3.11' + - cairosvg ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-autobuild ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-mock ; extra == 'dev' + - coverage[toml] ; extra == 'dev' + - wheel ; extra == 'dev' + - pre-commit ; extra == 'dev' + - sphinx ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - cairosvg ; extra == 'png' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-mock ; extra == 'tests' + - coverage[toml] ; extra == 'tests' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + sha256: d7421c54944dec04d2671e23196a15583d48f309d06fbcf995b5dfa6d586a5e9 + md5: 4dee387356d58bdc4b686ae3424fbd9e + depends: + - python >=3.10 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/invoke?source=hash-mapping + size: 133811 + timestamp: 1775579645825 +- pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + name: ipydatawidgets + version: 4.3.5 + sha256: d590cdb7c364f2f6ab346f20b9d2dd661d27a834ef7845bc9d7113118f05ec87 + requires_dist: + - ipywidgets>=7.0.0 + - numpy + - traittypes>=0.2.0 + - sphinx ; extra == 'docs' + - recommonmark ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - pytest>=4 ; extra == 'test' + - pytest-cov ; extra == 'test' + - nbval>=0.9.2 ; extra == 'test' + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + sha256: 5c1f3e874adaf603449f2b135d48f168c5d510088c78c229bda0431268b43b27 + md5: 4b53d436f3fbc02ce3eeaf8ae9bebe01 + depends: + - appnope + - __osx + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=hash-mapping + size: 132260 + timestamp: 1770566135697 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 + md5: b3a7d5842f857414d9ae831a799444dd + depends: + - __win + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=hash-mapping + size: 132382 + timestamp: 1770566174387 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + sha256: b77ed58eb235e5ad80e742b03caeed4bbc2a2ef064cb9a2deee3b75dfae91b2a + md5: 8b267f517b81c13594ed68d646fd5dcb + depends: + - __linux + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=hash-mapping + size: 133644 + timestamp: 1770566133040 +- pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + name: ipympl + version: 0.10.0 + sha256: a09c4f0ff86490cc62aed45e53b912fb706e3ec3506c4a51ce4a670d6667f5ce + requires_dist: + - ipython<10 + - ipywidgets>=7.6.0,<9 + - matplotlib>=3.5.0,<4 + - numpy + - pillow + - traitlets<6 + - intersphinx-registry ; extra == 'docs' + - myst-nb ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-thebe ; extra == 'docs' + - sphinx-togglebutton ; extra == 'docs' + - sphinx>=1.5 ; extra == 'docs' + - nbval>=0.11.0 ; extra == 'test' + - pytest>=9.0.2 ; extra == 'test' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + sha256: a0af49948a1842dfd15a0b0b2fd56c94ddbd07e07a6c8b4bc70d43015eafaff0 + md5: 73e9657cd19605740d21efb14d8d0cb9 + depends: + - __unix + - decorator >=5.1.0 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.2 + - matplotlib-inline >=0.1.6 + - prompt-toolkit >=3.0.41,<3.1.0 + - psutil >=7 + - pygments >=2.14.0 + - python >=3.11 + - stack_data >=0.6.0 + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - pexpect >4.6 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython?source=compressed-mapping + size: 651632 + timestamp: 1777038396606 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + sha256: f252ec33597115ff21cbb31051f6f9be34ca36cbbbf3d266b597660d8d8edde9 + md5: 5631ab99e902463d9dd4221e5b4eab6d + depends: + - __win + - decorator >=5.1.0 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.2 + - matplotlib-inline >=0.1.6 + - prompt-toolkit >=3.0.41,<3.1.0 + - psutil >=7 + - pygments >=2.14.0 + - python >=3.11 + - stack_data >=0.6.0 + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - colorama >=0.4.4 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython?source=compressed-mapping + size: 650593 + timestamp: 1777038425499 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 + md5: bd80ba060603cc228d9d81c257093119 + depends: + - pygments + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython-pygments-lexers?source=hash-mapping + size: 13993 + timestamp: 1737123723464 +- pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + name: ipywidgets + version: 8.1.8 + sha256: ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e + requires_dist: + - comm>=0.1.3 + - ipython>=6.1.0 + - traitlets>=4.3.1 + - widgetsnbextension~=4.0.14 + - jupyterlab-widgets~=3.0.15 + - jsonschema ; extra == 'test' + - ipykernel ; extra == 'test' + - pytest>=3.6.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytz ; extra == 'test' + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + sha256: 08e838d29c134a7684bca0468401d26840f41c92267c4126d7b43a6b533b0aed + md5: 0b0154421989637d424ccf0f104be51a + depends: + - arrow >=0.15.0 + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/isoduration?source=hash-mapping + size: 19832 + timestamp: 1733493720346 +- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 + md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 + depends: + - parso >=0.8.3,<0.9.0 + - python >=3.9 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/jedi?source=hash-mapping + size: 843646 + timestamp: 1733300981994 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b + md5: 04558c96691bed63104678757beb4f8d + depends: + - markupsafe >=2.0 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jinja2?source=compressed-mapping + size: 120685 + timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + sha256: a36789229ca9ce5315265b9d425abce9acb4691f5864aea69e935020545a9acb + md5: 974c5b3e353f031cfcf2365c9d375926 + depends: + - jinja2 + - python >=3.9 + - pyyaml + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/jinja2-ansible-filters?source=hash-mapping + size: 20315 + timestamp: 1734906203051 +- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + sha256: 9daa95bd164c8fa23b3ab196e906ef806141d749eddce2a08baa064f722d25fa + md5: 1269891272187518a0a75c286f7d0bbf + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/json5?source=compressed-mapping + size: 34731 + timestamp: 1774655440045 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + sha256: a3d10301b6ff399ba1f3d39e443664804a3d28315a4fb81e745b6817845f70ae + md5: 89bf346df77603055d3c8fe5811691e6 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jsonpointer?source=hash-mapping + size: 14190 + timestamp: 1774311356147 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 + md5: ada41c863af263cc4c5fcbaff7c3e4dc + depends: + - attrs >=22.2.0 + - jsonschema-specifications >=2023.3.6 + - python >=3.10 + - referencing >=0.28.4 + - rpds-py >=0.25.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/jsonschema?source=hash-mapping + size: 82356 + timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 + md5: 439cd0f567d697b20a8f45cb70a1005a + depends: + - python >=3.10 + - referencing >=0.31.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/jsonschema-specifications?source=hash-mapping + size: 19236 + timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + sha256: 6886fc61e4e4edd38fd38729976b134e8bd2143f7fce56cc80d7ac7bac99bce1 + md5: 8368d58342d0825f0843dc6acdd0c483 + depends: + - jsonschema >=4.26.0,<4.26.1.0a0 + - fqdn + - idna + - isoduration + - jsonpointer >1.13 + - rfc3339-validator + - rfc3986-validator >0.1.0 + - rfc3987-syntax >=1.1.0 + - uri-template + - webcolors >=24.6.0 + license: MIT + license_family: MIT + purls: [] + size: 4740 + timestamp: 1767839954258 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e + md5: 0c3b465ceee138b9c39279cc02e5c4a0 + depends: + - importlib-metadata >=4.8.3 + - jupyter_server >=1.1.2 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-lsp?source=compressed-mapping + size: 61633 + timestamp: 1775136333147 +- pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + name: jupyter-notebook-parser + version: 0.1.4 + sha256: 27b3b67cf898684e646d569f017cb27046774ad23866cb0bdf51d5f76a46476b + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + sha256: e402bd119720862a33229624ec23645916a7d47f30e1711a4af9e005162b84f3 + md5: 8a3d6d0523f66cf004e563a50d9392b3 + depends: + - jupyter_core >=5.1 + - python >=3.10 + - python-dateutil >=2.8.2 + - pyzmq >=25.0 + - tornado >=6.4.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-client?source=hash-mapping + size: 112785 + timestamp: 1767954655912 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc + md5: a8db462b01221e9f5135be466faeb3e0 + depends: + - __win + - pywin32 + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 64679 + timestamp: 1760643889625 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a + md5: b38fe4e78ee75def7e599843ef4c1ab0 + depends: + - __unix + - python + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 65503 + timestamp: 1760643864586 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + sha256: c7edb5682c6316a95ad781dccb1b6589cd2ec0bf94f23c21152974eb0363b5d7 + md5: bf42ee94c750c0b2e7e998b79ac299ea + depends: + - jsonschema-with-format-nongpl >=4.18.0 + - packaging + - python >=3.10 + - python-json-logger >=2.0.4 + - pyyaml >=5.3 + - referencing + - rfc3339-validator + - rfc3986-validator >=0.1.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-events?source=compressed-mapping + size: 24002 + timestamp: 1776861872237 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + sha256: 04fb8ea7749f67abaf76df6257bf86688e1389ceed55eb4fb0176fd2e882dbd6 + md5: 5ee7945accf0f215ddd6055d25d7cd83 + depends: + - anyio >=3.1.0 + - argon2-cffi >=21.1 + - jinja2 >=3.0.3 + - jupyter_client >=7.4.4 + - jupyter_core >=4.12,!=5.0.* + - jupyter_events >=0.11.0 + - jupyter_server_terminals >=0.4.4 + - nbconvert-core >=6.4.4 + - nbformat >=5.3.0 + - overrides >=5.0 + - packaging >=22.0 + - prometheus_client >=0.9 + - python >=3.10 + - pyzmq >=24 + - send2trash >=1.8.2 + - terminado >=0.8.3 + - tornado >=6.2.0 + - traitlets >=5.6.0 + - websocket-client >=1.7 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/jupyter-server?source=compressed-mapping + size: 360522 + timestamp: 1778060967727 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 + md5: 7b8bace4943e0dc345fc45938826f2b8 + depends: + - python >=3.10 + - terminado >=0.8.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-server-terminals?source=hash-mapping + size: 22052 + timestamp: 1768574057200 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + sha256: b85befad5ba1f50c0cc042a2ffb26441d13ffc2f18572dc20d3541476da0c7b9 + md5: 2ffe77234070324e763a6eddabb5f467 + depends: + - async-lru >=1.0.0 + - httpx >=0.25.0,<1 + - ipykernel >=6.5.0,!=6.30.0 + - jinja2 >=3.0.3 + - jupyter-lsp >=2.0.0 + - jupyter_core + - jupyter_server >=2.4.0,<3 + - jupyterlab_server >=2.28.0,<3 + - notebook-shim >=0.2 + - packaging + - python >=3.10 + - setuptools >=41.1.0 + - tomli >=1.2.2 + - tornado >=6.2.0 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab?source=compressed-mapping + size: 8861204 + timestamp: 1777483115382 +- pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + name: jupyterlab-widgets + version: 3.0.16 + sha256: 45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 + md5: fd312693df06da3578383232528c468d + depends: + - pygments >=2.4.1,<3 + - python >=3.9 + constrains: + - jupyterlab >=4.0.8,<5.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-pygments?source=hash-mapping + size: 18711 + timestamp: 1733328194037 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee + md5: a63877cb23de826b1620d3adfccc4014 + depends: + - babel >=2.10 + - jinja2 >=3.0.3 + - json5 >=0.9.0 + - jsonschema >=4.18 + - jupyter_server >=1.21,<3 + - packaging >=21.3 + - python >=3.10 + - requests >=2.31 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-server?source=hash-mapping + size: 51621 + timestamp: 1761145478692 +- pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + name: jupyterquiz + version: 2.9.6.4 + sha256: f8c4418f6c827454523fc882a30d744b585cb58ac1ae277769c3059d04fc272b +- pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + name: jupytext + version: 1.19.1 + sha256: d8975035155d034bdfde5c0c37891425314b7ea8d3a6c4b5d18c294348714cd9 + requires_dist: + - markdown-it-py>=1.0 + - mdit-py-plugins + - nbformat + - packaging + - pyyaml + - tomli ; python_full_version < '3.11' + - autopep8 ; extra == 'dev' + - black ; extra == 'dev' + - flake8 ; extra == 'dev' + - gitpython ; extra == 'dev' + - ipykernel ; extra == 'dev' + - isort ; extra == 'dev' + - jupyter-fs[fs]>=1.0 ; extra == 'dev' + - jupyter-server!=2.11 ; extra == 'dev' + - marimo>=0.17.6,<=0.19.4 ; extra == 'dev' + - nbconvert ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-asyncio ; extra == 'dev' + - pytest-cov>=2.6.1 ; extra == 'dev' + - pytest-randomly ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-gallery>=0.8 ; extra == 'dev' + - myst-parser ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-randomly ; extra == 'test' + - pytest-xdist ; extra == 'test' + - black ; extra == 'test-cov' + - ipykernel ; extra == 'test-cov' + - jupyter-server!=2.11 ; extra == 'test-cov' + - nbconvert ; extra == 'test-cov' + - pytest ; extra == 'test-cov' + - pytest-asyncio ; extra == 'test-cov' + - pytest-cov>=2.6.1 ; extra == 'test-cov' + - pytest-randomly ; extra == 'test-cov' + - pytest-xdist ; extra == 'test-cov' + - autopep8 ; extra == 'test-external' + - black ; extra == 'test-external' + - flake8 ; extra == 'test-external' + - gitpython ; extra == 'test-external' + - ipykernel ; extra == 'test-external' + - isort ; extra == 'test-external' + - jupyter-fs[fs]>=1.0 ; extra == 'test-external' + - jupyter-server!=2.11 ; extra == 'test-external' + - marimo>=0.17.6,<=0.19.4 ; extra == 'test-external' + - nbconvert ; extra == 'test-external' + - pre-commit ; extra == 'test-external' + - pytest ; extra == 'test-external' + - pytest-asyncio ; extra == 'test-external' + - pytest-randomly ; extra == 'test-external' + - pytest-xdist ; extra == 'test-external' + - sphinx ; extra == 'test-external' + - sphinx-gallery>=0.8 ; extra == 'test-external' + - black ; extra == 'test-functional' + - pytest ; extra == 'test-functional' + - pytest-asyncio ; extra == 'test-functional' + - pytest-randomly ; extra == 'test-functional' + - pytest-xdist ; extra == 'test-functional' + - black ; extra == 'test-integration' + - ipykernel ; extra == 'test-integration' + - jupyter-server!=2.11 ; extra == 'test-integration' + - nbconvert ; extra == 'test-integration' + - pytest ; extra == 'test-integration' + - pytest-asyncio ; extra == 'test-integration' + - pytest-randomly ; extra == 'test-integration' + - pytest-xdist ; extra == 'test-integration' + - bash-kernel ; extra == 'test-ui' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + purls: [] + size: 134088 + timestamp: 1754905959823 +- pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl + name: kiwisolver + version: 1.5.0 + sha256: 0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.5.0 + sha256: 332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.5.0 + sha256: 2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + name: kiwisolver + version: 1.5.0 + sha256: dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl + name: kiwisolver + version: 1.5.0 + sha256: beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + name: kiwisolver + version: 1.5.0 + sha256: 0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 + md5: fb53fb07ce46a575c5d004bbc96032c2 + depends: + - __glibc >=2.17,<3.0.a0 + - keyutils >=1.6.3,<2.0a0 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - libgcc >=14 + - libstdcxx >=14 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1386730 + timestamp: 1769769569681 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed + md5: e446e1822f4da8e5080a9de93474184d + depends: + - __osx >=11.0 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1160828 + timestamp: 1769770119811 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761 + md5: 4432f52dc0c8eb6a7a6abc00a037d93c + depends: + - openssl >=3.5.5,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 751055 + timestamp: 1769769688841 +- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 + md5: 9b965c999135d43a3d0f7bd7d024e26a + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/lark?source=hash-mapping + size: 94312 + timestamp: 1761596921009 +- pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + name: lazy-loader + version: '0.5' + sha256: ab0ea149e9c554d4ffeeb21105ac60bed7f3b4fd69b1d2360a4add51b170b005 + requires_dist: + - packaging + - pytest>=8.0 ; extra == 'test' + - pytest-cov>=5.0 ; extra == 'test' + - coverage[toml]>=7.2 ; extra == 'test' + - pre-commit==4.3.0 ; extra == 'lint' + - changelist==0.5 ; extra == 'dev' + - spin==0.15 ; extra == 'dev' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c + md5: 18335a698559cdbcd86150a48bf54ba6 + depends: + - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 728002 + timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + sha256: a7a4481a4d217a3eadea0ec489826a69070fcc3153f00443aa491ed21527d239 + md5: 6f7b4302263347698fd24565fbf11310 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + constrains: + - libabseil-static =20260107.1=cxx17* + - abseil-cpp =20260107.1 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1384817 + timestamp: 1770863194876 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + sha256: 756611fbb8d2957a5b4635d9772bd8432cb6ddac05580a6284cca6fdc9b07fca + md5: bb65152e0d7c7178c0f1ee25692c9fd1 + depends: + - __osx >=11.0 + - libcxx >=19 + constrains: + - abseil-cpp =20260107.1 + - libabseil-static =20260107.1=cxx17* + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1229639 + timestamp: 1770863511331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e + md5: 72c8fd1af66bd67bf580645b426513ed + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 79965 + timestamp: 1764017188531 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 + md5: 006e7ddd8a110771134fcc4e1e3a6ffa + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 79443 + timestamp: 1764017945924 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b + md5: 366b40a69f0ad6072561c1d09301c886 + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 34632 + timestamp: 1764017199083 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf + md5: 079e88933963f3f149054eec2c487bc2 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 29452 + timestamp: 1764017979099 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d + md5: 4ffbb341c8b616aa2494b6afb26a0c5f + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 298378 + timestamp: 1764017210931 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 + md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 290754 + timestamp: 1764018009077 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + sha256: 76c3d3c702593b6ef57dc2f99c082193a99835526634b844f4a78ae3aecdb6c8 + md5: d0a2e921c5a89df73118cff1afed5213 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 570968 + timestamp: 1778110367423 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b + depends: + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + sha256: ea33c40977ea7a2c3658c522230058395bc2ee0d89d99f0711390b6a1ee80d12 + md5: a3b390520c563d78cc58974de95a03e5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.8.0.* + license: MIT + license_family: MIT + purls: [] + size: 77241 + timestamp: 1777846112704 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + sha256: f4b1cafc59afaede8fa0a2d9cf376840f1c553001acd72f6ead18bbc8ac8c49c + md5: 65466e82c09e888ca7560c11a97d5450 + depends: + - __osx >=11.0 + constrains: + - expat 2.8.0.* + license: MIT + license_family: MIT + purls: [] + size: 68789 + timestamp: 1777846180142 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + sha256: 2d81d647c1f01108803457cac999b947456f44dd0a3c2325395677feacaeca67 + md5: 264e350e035092b5135a2147c238aec4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.0.* + license: MIT + license_family: MIT + purls: [] + size: 71094 + timestamp: 1777846223617 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 + md5: a360c33a5abe61c07959e449fa1453eb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 58592 + timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 + md5: 0aa00f03f9e39fb9876085dee11a85d4 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 1041788 + timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 + md5: d5e96b1ed75ca01906b3d2469b4ce493 + depends: + - libgcc 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27526 + timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 + md5: 239c5e9546c38a1e884d69effcf4c882 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 603262 + timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d + md5: b88d90cad08e6bc8ad540cb310a761fb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 113478 + timestamp: 1775825492909 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + sha256: 34878d87275c298f1a732c6806349125cebbf340d24c6c23727268184bba051e + md5: b1fd823b5ae54fbec272cea0811bd8a9 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 92472 + timestamp: 1775825802659 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 + md5: 8f83619ab1588b98dd99c90b0bfc5c6d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 106486 + timestamp: 1775825663227 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 + md5: 2c21e66f50753a083cbe6b80f38268fa + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 92400 + timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 + md5: 57c4be259f5e0b99a5983799a228ae55 + depends: + - __osx >=11.0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 73690 + timestamp: 1769482560514 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 + md5: e4a9fc2bba3b022dad998c78856afe47 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 89411 + timestamp: 1769482314283 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f + md5: 2a45e7f8af083626f009645a6481f12d + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.6,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 663344 + timestamp: 1773854035739 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a + md5: 6ea18834adbc3b33df9bd9fb45eaf95b + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 576526 + timestamp: 1773854624224 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 + md5: d864d34357c3b65a4b731f78c0801dc4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-only + license_family: GPL + purls: [] + size: 33731 + timestamp: 1750274110928 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + sha256: 64e5c80cbce4680a2d25179949739a6def695d72c40ca28f010711764e372d97 + md5: 7af961ef4aa2c1136e11dd43ded245ab + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: ISC + purls: [] + size: 277661 + timestamp: 1772479381288 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + sha256: df603472ea1ebd8e7d4fb71e4360fe48d10b11c240df51c129de1da2ff9e8227 + md5: 7cc5247987e6d115134ebab15186bc13 + depends: + - __osx >=11.0 + license: ISC + purls: [] + size: 248039 + timestamp: 1772479570912 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + sha256: d915f4fa8ebbf237c7a6e511ed458f2cfdc7c76843a924740318a15d0dd33d6d + md5: da2aa614d16a795b3007b6f4a1318a81 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: ISC + purls: [] + size: 276860 + timestamp: 1772479407566 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d + md5: 7dc38adcbf71e6b38748e919e16e0dce + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 954962 + timestamp: 1777986471789 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + sha256: 49daec7c83e70d4efc17b813547824bc2bcf2f7256d84061d24fbfe537da9f74 + md5: 6681822ea9d362953206352371b6a904 + depends: + - __osx >=11.0 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 920047 + timestamp: 1777987051643 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + sha256: e70562450332ca8954bc16f3455468cca5ef3695c7d7187ecc87f8fc3c70e9eb + md5: 7fea434a17c323256acc510a041b80d7 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1304178 + timestamp: 1777986510497 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e + md5: 1b08cd684f34175e4514474793d44bcb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_18 + constrains: + - libstdcxx-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 5852330 + timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + sha256: bc1b08c92626c91500fd9f26f2c797f3eb153b627d53e9c13cd167f1e12b2829 + md5: 38ffe67b78c9d4de527be8315e5ada2c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 40297 + timestamp: 1775052476770 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 421195 + timestamp: 1753948426421 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc + depends: + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 + md5: d87ff7921124eccd67248aa483c23fec + depends: + - __glibc >=2.17,<3.0.a0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 63629 + timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 + md5: bc5a5721b6439f2f62a84f2548136082 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 47759 + timestamp: 1774072956767 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 + md5: dbabbd6234dea34040e631f87676292f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 58347 + timestamp: 1774072851498 +- pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: llvmlite + version: 0.47.0 + sha256: 2699a74321189e812d476a43d6d7f652f51811e7b5aad9d9bba842a1c7927acb + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/34/0b/b9d1911cfefa61399821dfb37f486d83e0f42630a8d12f7194270c417002/llvmlite-0.47.0-cp311-cp311-macosx_11_0_arm64.whl + name: llvmlite + version: 0.47.0 + sha256: 74090f0dcfd6f24ebbef3f21f11e38111c4d7e6919b54c4416e1e357c3446b07 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: llvmlite + version: 0.47.0 + sha256: ca14f02e29134e837982497959a8e2193d6035235de1cb41a9cb2bd6da4eedbb + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + name: llvmlite + version: 0.47.0 + sha256: c2e9adf8698d813a9a5efb2d4370caf344dbc1e145019851fee6a6f319ba760e + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + name: llvmlite + version: 0.47.0 + sha256: a3c6a735d4e1041808434f9d440faa3d78d9b4af2ee64d05a66f351883b6ceec + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl + name: llvmlite + version: 0.47.0 + sha256: c37d6eb7aaabfa83ab9c2ff5b5cdb95a5e6830403937b2c588b7490724e05327 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + name: lmfit + version: 1.3.4 + sha256: afce1593b42324d37ae2908249b0c55445e2f4c1a0474ff706a8e2f7b5d949fa + requires_dist: + - asteval>=1.0 + - numpy>=1.24 + - scipy>=1.10.0 + - uncertainties>=3.2.2 + - dill>=0.3.4 + - build ; extra == 'dev' + - check-wheel-contents ; extra == 'dev' + - flake8-pyproject ; extra == 'dev' + - pre-commit ; extra == 'dev' + - twine ; extra == 'dev' + - cairosvg ; extra == 'doc' + - corner ; extra == 'doc' + - emcee>=3.0.0 ; extra == 'doc' + - ipykernel ; extra == 'doc' + - jupyter-sphinx>=0.2.4 ; extra == 'doc' + - matplotlib ; extra == 'doc' + - numdifftools ; extra == 'doc' + - pandas ; extra == 'doc' + - pillow ; extra == 'doc' + - pycairo ; sys_platform == 'win32' and extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-gallery>=0.10 ; extra == 'doc' + - sphinxcontrib-svg2pdfconverter ; extra == 'doc' + - sympy ; extra == 'doc' + - coverage ; extra == 'test' + - flaky ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - lmfit[dev,doc,test] ; extra == 'all' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + name: locket + version: 1.0.0 + sha256: b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl + name: lxml + version: 6.1.0 + sha256: 183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + name: lxml + version: 6.1.0 + sha256: a0092f2b107b69601adf562a57c956fbb596e05e3e6651cabd3054113b007e45 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl + name: lxml + version: 6.1.0 + sha256: cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl + name: lxml + version: 6.1.0 + sha256: 4a1503c56e4e2b38dc76f2f2da7bae69670c0f1933e27cfa34b2fa5876410b16 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: lxml + version: 6.1.0 + sha256: 363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: lxml + version: 6.1.0 + sha256: e69aa6805905807186eb00e66c6d97a935c928275182eb02ee40ba00da9623b2 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + name: mando + version: 0.7.1 + sha256: 26ef1d70928b6057ee3ca12583d73c63e05c49de8972d620c278a7b206581a8a + requires_dist: + - six + - argparse ; python_full_version < '2.7' + - funcsigs ; python_full_version < '3.3' + - rst2ansi ; extra == 'restructuredtext' +- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + name: markdown + version: 3.10.2 + sha256: e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36 + requires_dist: + - coverage ; extra == 'testing' + - pyyaml ; extra == 'testing' + - mkdocs>=1.6 ; extra == 'docs' + - mkdocs-nature>=0.6 ; extra == 'docs' + - mdx-gh-links>=0.2 ; extra == 'docs' + - mkdocstrings[python]>=0.28.3 ; extra == 'docs' + - mkdocs-gen-files ; extra == 'docs' + - mkdocs-section-index ; extra == 'docs' + - mkdocs-literate-nav ; extra == 'docs' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + name: markdown-it-py + version: 4.1.0 + sha256: d4939a62a2dd0cd9cb80a191a711ba1d39bac8ed5ef9e9966895b0171c01c46d + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + name: markdown-it-py + version: 4.2.0 + sha256: 9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda + sha256: 710e207b2e91308a34bcfe547c60ad86c1fa294827266ba18548c1fe1a9d8333 + md5: f9efdf9b0f3d0cc309d56af6edf2a6b0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 26756 + timestamp: 1772445078834 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + sha256: 72ed7c0216541d65a17b171bf2eec4a3b81e9158d8ed48e59e1ecd3ae302d263 + md5: aeb9b9da79fd0258b3db091d1fefcd71 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 26100 + timestamp: 1772445154165 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda + sha256: d635f2b1d9e19e8e68c5d33150f7e4f62df08ef2ef0e85977f743e81939afc01 + md5: ff068874356bbc7f9bd2d793f809f44b + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=compressed-mapping + size: 26511 + timestamp: 1772445369187 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + sha256: f62892a42948c61aa0a13d9a36ff811651f0a1102331223594aecf3cc042bece + md5: 0195d558b0c0ab8f4af3089af83067c5 + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 26009 + timestamp: 1772445537524 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda + sha256: 3d37fb1900e31131f84549560e7a4bfea5f39aa3ecd73345fef1f33975cf0baa + md5: f55de41c947bdd2ff9bbeffedf8089f7 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 29362 + timestamp: 1772445178723 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + sha256: 9dc626b6c00bc2dbd2494df689876ff675b93d92636ba5df8e37b99040a1f6bc + md5: 5cc690ddf943700e0ef50a265df31f03 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 28992 + timestamp: 1772445161959 +- pypi: https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl + name: matplotlib + version: 3.10.9 + sha256: dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + name: matplotlib + version: 3.10.9 + sha256: b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: matplotlib + version: 3.10.9 + sha256: 8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl + name: matplotlib + version: 3.10.9 + sha256: d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: matplotlib + version: 3.10.9 + sha256: 8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + name: matplotlib + version: 3.10.9 + sha256: f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 + md5: 00e120ce3e40bad7bfc78861ce3c4a25 + depends: + - python >=3.10 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/matplotlib-inline?source=hash-mapping + size: 15175 + timestamp: 1761214578417 +- pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + name: mdit-py-plugins + version: 0.5.0 + sha256: 07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f + requires_dist: + - markdown-it-py>=2.0.0,<5.0.0 + - pre-commit ; extra == 'code-style' + - myst-parser ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + name: mdurl + version: 0.1.2 + sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + name: mergedeep + version: 1.3.4 + sha256: 70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307 + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + name: mike + version: 2.2.0 + sha256: e1f4981c1152eec7c2490a3401142292cc47d686194188416db2648fdfe1d040 + requires_dist: + - jinja2>=2.7 + - mkdocs~=1.0 + - pyparsing>=3.0 + - pyyaml>=5.1 + - pyyaml-env-tag + - verspec + - importlib-metadata ; python_full_version < '3.10' + - importlib-resources ; python_full_version < '3.10' + - coverage ; extra == 'dev' + - flake8-quotes ; extra == 'dev' + - flake8>=3.0 ; extra == 'dev' + - shtab ; extra == 'dev' + - coverage ; extra == 'test' + - flake8-quotes ; extra == 'test' + - flake8>=3.0 ; extra == 'test' + - shtab ; extra == 'test' +- conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + sha256: b52dc6c78fbbe7a3008535cb8bfd87d70d8053e9250bbe16e387470a9df07070 + md5: b97e84d1553b4a1c765b87fff83453ad + depends: + - python >=3.10 + - typing_extensions + - python + license: BSD-3-Clause + purls: + - pkg:pypi/mistune?source=compressed-mapping + size: 74567 + timestamp: 1777824616382 +- pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + name: mkdocs + version: 1.6.1 + sha256: db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e + requires_dist: + - click>=7.0 + - colorama>=0.4 ; sys_platform == 'win32' + - ghp-import>=1.0 + - importlib-metadata>=4.4 ; python_full_version < '3.10' + - jinja2>=2.11.1 + - markdown>=3.3.6 + - markupsafe>=2.0.1 + - mergedeep>=1.3.4 + - mkdocs-get-deps>=0.2.0 + - packaging>=20.5 + - pathspec>=0.11.1 + - pyyaml-env-tag>=0.1 + - pyyaml>=5.1 + - watchdog>=2.0 + - babel>=2.9.0 ; extra == 'i18n' + - babel==2.9.0 ; extra == 'min-versions' + - click==7.0 ; extra == 'min-versions' + - colorama==0.4 ; sys_platform == 'win32' and extra == 'min-versions' + - ghp-import==1.0 ; extra == 'min-versions' + - importlib-metadata==4.4 ; python_full_version < '3.10' and extra == 'min-versions' + - jinja2==2.11.1 ; extra == 'min-versions' + - markdown==3.3.6 ; extra == 'min-versions' + - markupsafe==2.0.1 ; extra == 'min-versions' + - mergedeep==1.3.4 ; extra == 'min-versions' + - mkdocs-get-deps==0.2.0 ; extra == 'min-versions' + - packaging==20.5 ; extra == 'min-versions' + - pathspec==0.11.1 ; extra == 'min-versions' + - pyyaml-env-tag==0.1 ; extra == 'min-versions' + - pyyaml==5.1 ; extra == 'min-versions' + - watchdog==2.0 ; extra == 'min-versions' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + name: mkdocs-autorefs + version: 1.4.4 + sha256: 834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089 + requires_dist: + - markdown>=3.3 + - markupsafe>=2.0.1 + - mkdocs>=1.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + name: mkdocs-get-deps + version: 0.2.2 + sha256: e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650 + requires_dist: + - importlib-metadata>=4.3 ; python_full_version < '3.10' + - mergedeep>=1.3.4 + - platformdirs>=2.2.0 + - pyyaml>=5.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + name: mkdocs-jupyter + version: 0.26.3 + sha256: cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82 + requires_dist: + - ipykernel>6.0.0,<8 + - jupytext>1.13.8,<2 + - mkdocs-material>9.0.0 + - mkdocs>=1.4.0,<2 + - nbconvert>=7.2.9,<8 + - pygments>2.12.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + name: mkdocs-markdownextradata-plugin + version: 0.2.6 + sha256: 34dd40870781784c75809596b2d8d879da783815b075336d541de1f150c94242 + requires_dist: + - mkdocs + - pyyaml + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + name: mkdocs-material + version: 9.7.6 + sha256: 71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba + requires_dist: + - babel>=2.10 + - backrefs>=5.7.post1 + - colorama>=0.4 + - jinja2>=3.1 + - markdown>=3.2 + - mkdocs-material-extensions>=1.3 + - mkdocs>=1.6,<2 + - paginate>=0.5 + - pygments>=2.16 + - pymdown-extensions>=10.2 + - requests>=2.30 + - mkdocs-git-committers-plugin-2>=1.1 ; extra == 'git' + - mkdocs-git-revision-date-localized-plugin>=1.2.4 ; extra == 'git' + - cairosvg>=2.6 ; extra == 'imaging' + - pillow>=10.2 ; extra == 'imaging' + - mkdocs-minify-plugin>=0.7 ; extra == 'recommended' + - mkdocs-redirects>=1.2 ; extra == 'recommended' + - mkdocs-rss-plugin>=1.6 ; extra == 'recommended' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + name: mkdocs-material-extensions + version: 1.3.1 + sha256: adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + name: mkdocs-plugin-inline-svg + version: 0.1.0 + sha256: a5aab2d98a19b24019f8e650f54fc647c2f31e7d0e36fc5cf2d2161acc0ea49a + requires_dist: + - mkdocs + requires_python: '>=3.5' +- pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + name: mkdocstrings + version: 1.0.4 + sha256: 63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b + requires_dist: + - jinja2>=3.1 + - markdown>=3.6 + - markupsafe>=1.1 + - mkdocs>=1.6 + - mkdocs-autorefs>=1.4 + - pymdown-extensions>=6.3 + - mkdocstrings-crystal>=0.3.4 ; extra == 'crystal' + - mkdocstrings-python-legacy>=0.2.1 ; extra == 'python-legacy' + - mkdocstrings-python>=1.16.2 ; extra == 'python' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + name: mkdocstrings-python + version: 2.0.3 + sha256: 0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 + requires_dist: + - mkdocstrings>=0.30 + - mkdocs-autorefs>=1.4 + - griffelib>=2.0 + - typing-extensions>=4.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + name: mpld3 + version: 0.5.12 + sha256: bea31799a4041029a906f53f2662bbf1c49903e0c0bc712b412354158ec7cf54 + requires_dist: + - jinja2 + - matplotlib +- pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + name: mpltoolbox + version: 26.2.0 + sha256: cd2668db4216fc4d7c2ba37974961aa61445f1517527b645b6082930e35ba7f0 + requires_dist: + - matplotlib + - ipympl ; extra == 'test' + - pytest>=8.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + name: mpmath + version: 1.3.0 + sha256: a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c + requires_dist: + - pytest>=4.6 ; extra == 'develop' + - pycodestyle ; extra == 'develop' + - pytest-cov ; extra == 'develop' + - codecov ; extra == 'develop' + - wheel ; extra == 'develop' + - sphinx ; extra == 'docs' + - gmpy2>=2.1.0a4 ; platform_python_implementation != 'PyPy' and extra == 'gmpy' + - pytest>=4.6 ; extra == 'tests' +- pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl + name: msgpack + version: 1.1.2 + sha256: d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + name: msgpack + version: 1.1.2 + sha256: a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: 454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda + sha256: 59123ba4af69c1e7ca6b1b8ffcc40f2aff9a635814495bda3f4f555b3b929165 + md5: 0347d2804701019ac005528df9eb502c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 217556 + timestamp: 1776337480302 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + sha256: a44d23085117672e4e19629ea3e6c53f516984322513c4bfdd052b1c7c6fc8ad + md5: 15c679f7133347d68058b688f3519cea + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 219767 + timestamp: 1776337423071 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda + sha256: 55ce08c77b6e87fcc5cca61a516e81fdcc1cd0969e0204fce0a32ca84118a148 + md5: 24707aa446fa7babd806397b8c5349a2 + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 207945 + timestamp: 1776338655947 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + sha256: 63cdc0052bd638f1f3df6de438e69275b7b273b4b77dbd1ac34ce25d98cf973c + md5: 2dd8d3b25e88780abc058559bc7975c6 + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 214497 + timestamp: 1776338358818 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda + sha256: d096ad02a47a61aeeade2ad3639cc300adf950790cca097717040d46ca5bff52 + md5: 6e6fd9a9012358254bebee33eb3d7f71 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 199272 + timestamp: 1776337711230 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + sha256: 4e70a7b9bee6b9dadd1f038da6fcf1627cc53581d1cc01355b66d638ae55c0e3 + md5: 96575971ffc81497b83bf321f0b9e945 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 201017 + timestamp: 1776337591817 +- pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: 935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + name: multidict + version: 6.7.1 + sha256: 960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl + name: multidict + version: 6.7.1 + sha256: bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + name: narwhals + version: 2.20.0 + sha256: 16e750ea5507d4ba6e8d03455b5f93a535e0405976561baea235bca5dc9f475d + requires_dist: + - cudf-cu12>=24.10.0 ; extra == 'cudf' + - dask[dataframe]>=2024.8 ; extra == 'dask' + - duckdb>=1.1 ; extra == 'duckdb' + - ibis-framework>=6.0.0 ; extra == 'ibis' + - packaging ; extra == 'ibis' + - pyarrow-hotfix ; extra == 'ibis' + - rich ; extra == 'ibis' + - modin ; extra == 'modin' + - pandas>=1.1.3 ; extra == 'pandas' + - polars>=0.20.4 ; extra == 'polars' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - pyspark>=3.5.0 ; extra == 'pyspark' + - pyspark[connect]>=3.5.0 ; extra == 'pyspark-connect' + - duckdb>=1.1 ; extra == 'sql' + - sqlparse ; extra == 'sql' + - sqlframe>=3.22.0,!=3.39.3 ; extra == 'sqlframe' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + sha256: 1b66960ee06874ddceeebe375d5f17fb5f393d025a09e15b830ad0c4fffb585b + md5: 00f5b8dafa842e0c27c1cd7296aa4875 + depends: + - jupyter_client >=6.1.12 + - jupyter_core >=4.12,!=5.0.* + - nbformat >=5.1 + - python >=3.8 + - traitlets >=5.4 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbclient?source=compressed-mapping + size: 28473 + timestamp: 1766485646962 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 + md5: 2bce0d047658a91b99441390b9b27045 + depends: + - beautifulsoup4 + - bleach-with-css !=5.0.0 + - defusedxml + - importlib-metadata >=3.6 + - jinja2 >=3.0 + - jupyter_core >=4.7 + - jupyterlab_pygments + - markupsafe >=2.0 + - mistune >=2.0.3,<4 + - nbclient >=0.5.0 + - nbformat >=5.7 + - packaging + - pandocfilters >=1.4.1 + - pygments >=2.4.1 + - python >=3.10 + - traitlets >=5.1 + - python + constrains: + - pandoc >=2.9.2,<4.0.0 + - nbconvert ==7.17.1 *_0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbconvert?source=compressed-mapping + size: 202229 + timestamp: 1775615493260 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + sha256: 7a5bd30a2e7ddd7b85031a5e2e14f290898098dc85bea5b3a5bf147c25122838 + md5: bbe1963f1e47f594070ffe87cdf612ea + depends: + - jsonschema >=2.6 + - jupyter_core >=4.12,!=5.0.* + - python >=3.9 + - python-fastjsonschema >=2.15 + - traitlets >=5.1 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbformat?source=hash-mapping + size: 100945 + timestamp: 1733402844974 +- pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + name: nbmake + version: 1.5.5 + sha256: c6fbe6e48b60cacac14af40b38bf338a3b88f47f085c54ac5b8639ff0babaf4b + requires_dist: + - ipykernel>=5.4.0 + - nbclient>=0.6.6 + - nbformat>=5.0.4 + - pygments>=2.7.3 + - pytest>=6.1.0 + requires_python: '>=3.8.0' +- pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + name: nbqa + version: 1.9.1 + sha256: 95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5 + requires_dist: + - autopep8>=1.5 + - ipython>=7.8.0 + - tokenize-rt>=3.2.0 + - tomli + - black ; extra == 'toolchain' + - blacken-docs ; extra == 'toolchain' + - flake8 ; extra == 'toolchain' + - isort ; extra == 'toolchain' + - jupytext ; extra == 'toolchain' + - mypy ; extra == 'toolchain' + - pylint ; extra == 'toolchain' + - pyupgrade ; extra == 'toolchain' + - ruff ; extra == 'toolchain' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + name: nbstripout + version: 0.9.1 + sha256: ca027ee45742ee77e4f8e9080254f9a707f1161ba11367b82fdf4a29892c759e + requires_dist: + - nbformat + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl + name: ncrystal + version: 4.4.2 + sha256: e02fa7d743addc3fbea23287737a88b8d01192450fdca51554d3f9032fe4617c + requires_dist: + - ncrystal-core==4.4.2 + - ncrystal-python==4.4.2 + - spglib>=2.1.0 ; extra == 'composer' + - ase>=3.23.0 ; extra == 'cif' + - gemmi>=0.6.1 ; extra == 'cif' + - spglib>=2.1.0 ; extra == 'cif' + - endf-parserpy>=0.14.3 ; extra == 'endf' + - matplotlib>=3.6.0 ; extra == 'plot' + - ase>=3.23.0 ; extra == 'all' + - endf-parserpy>=0.14.3 ; extra == 'all' + - gemmi>=0.6.1 ; extra == 'all' + - matplotlib>=3.6.0 ; extra == 'all' + - spglib>=2.1.0 ; extra == 'all' + - pyyaml>=6.0.0 ; extra == 'devel' + - ase>=3.23.0 ; extra == 'devel' + - cppcheck ; extra == 'devel' + - endf-parserpy>=0.14.3 ; extra == 'devel' + - gemmi>=0.6.1 ; extra == 'devel' + - matplotlib>=3.6.0 ; extra == 'devel' + - mpmath>=1.3.0 ; extra == 'devel' + - numpy>=1.22 ; extra == 'devel' + - pybind11>=2.11.0 ; extra == 'devel' + - ruff>=0.8.1 ; extra == 'devel' + - simple-build-system>=1.6.0 ; extra == 'devel' + - spglib>=2.1.0 ; extra == 'devel' + - tomli>=2.0.0 ; python_full_version < '3.11' and extra == 'devel' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c7/6b/6c02f55c2ce2f137ccca0986be7dd89bea31d5bee4346b4377fa3b8586df/ncrystal_core-4.4.2-py3-none-win_amd64.whl + name: ncrystal-core + version: 4.4.2 + sha256: 9b28a90b63849e6a3a807a0a59f7c2ee57e4c64f5643b2dcb6a798ac8ccf666a + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl + name: ncrystal-core + version: 4.4.2 + sha256: b7e6101a6850aa18cf441825214381614db444ffcba648de8266fe1c4d1024ce + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: ncrystal-core + version: 4.4.2 + sha256: d0d9c47cd017b7cefc52dde50546d7c151bfdd75d345e42e2b3e74ab5fe83c62 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl + name: ncrystal-python + version: 4.4.2 + sha256: f419318d088fade6bcff1e39e15baf6fe69fcf5306dd681fca1106d1f63a89ce + requires_dist: + - numpy>=1.22 + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 + md5: fc21868a1a5aacc937e7a18747acb8a5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: X11 AND BSD-3-Clause + purls: [] + size: 918956 + timestamp: 1777422145199 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d + md5: 343d10ed5b44030a2f67193905aea159 + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + purls: [] + size: 805509 + timestamp: 1777423252320 +- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 + md5: 598fd7d4d0de2455fb74f56063969a97 + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/nest-asyncio?source=hash-mapping + size: 11543 + timestamp: 1733325673691 +- pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + name: networkx + version: 3.6.1 + sha256: d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 + requires_dist: + - asv ; extra == 'benchmarking' + - virtualenv ; extra == 'benchmarking' + - numpy>=1.25 ; extra == 'default' + - scipy>=1.11.2 ; extra == 'default' + - matplotlib>=3.8 ; extra == 'default' + - pandas>=2.0 ; extra == 'default' + - pre-commit>=4.1 ; extra == 'developer' + - mypy>=1.15 ; extra == 'developer' + - sphinx>=8.0 ; extra == 'doc' + - pydata-sphinx-theme>=0.16 ; extra == 'doc' + - sphinx-gallery>=0.18 ; extra == 'doc' + - numpydoc>=1.8.0 ; extra == 'doc' + - pillow>=10 ; extra == 'doc' + - texext>=0.6.7 ; extra == 'doc' + - myst-nb>=1.1 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - osmnx>=2.0.0 ; extra == 'example' + - momepy>=0.7.2 ; extra == 'example' + - contextily>=1.6 ; extra == 'example' + - seaborn>=0.13 ; extra == 'example' + - cairocffi>=1.7 ; extra == 'example' + - igraph>=0.11 ; extra == 'example' + - scikit-learn>=1.5 ; extra == 'example' + - iplotx>=0.9.0 ; extra == 'example' + - lxml>=4.6 ; extra == 'extra' + - pygraphviz>=1.14 ; extra == 'extra' + - pydot>=3.0.1 ; extra == 'extra' + - sympy>=1.10 ; extra == 'extra' + - build>=0.10 ; extra == 'release' + - twine>=4.0 ; extra == 'release' + - wheel>=0.40 ; extra == 'release' + - changelist==0.5 ; extra == 'release' + - pytest>=7.2 ; extra == 'test' + - pytest-cov>=4.0 ; extra == 'test' + - pytest-xdist>=3.0 ; extra == 'test' + - pytest-mpl ; extra == 'test-extras' + - pytest-randomly ; extra == 'test-extras' + requires_python: '>=3.11,!=3.14.1' +- pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + name: nodeenv + version: 1.10.0 + sha256: 5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' +- conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + sha256: d1a673d1418d9e956b6e4e46c23e72a511c5c1d45dc5519c947457427036d5e2 + md5: baffb1570b3918c784d4490babc52fbf + depends: + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.28,<3.0.a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libuv >=1.51.0,<2.0a0 + - c-ares >=1.34.6,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - libsqlite >=3.52.0,<4.0a0 + - icu >=78.3,<79.0a0 + - libzlib >=1.3.2,<2.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + - zstd >=1.5.7,<1.6.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + license: MIT + license_family: MIT + purls: [] + size: 18829340 + timestamp: 1774514313036 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + sha256: 4782b172b3b8a557b60bf5f591821cf100e2092ba7a5494ce047dfa41626de26 + md5: ca8277c52fdface8bb8ebff7cd9a6f56 + depends: + - libcxx >=19 + - __osx >=11.0 + - icu >=78.3,<79.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libuv >=1.51.0,<2.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + - c-ares >=1.34.6,<2.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + license: MIT + license_family: MIT + purls: [] + size: 17101803 + timestamp: 1774517834028 +- conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + sha256: 5e38e51da1aa4bc352db9b4cec1c3e25811de0f4408edaa24e009a64de6dbfdf + md5: e626ee7934e4b7cb21ce6b721cff8677 + license: MIT + license_family: MIT + purls: [] + size: 31271315 + timestamp: 1774517904472 +- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 + md5: e7f89ea5f7ea9401642758ff50a2d9c1 + depends: + - jupyter_server >=1.8,<3 + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/notebook-shim?source=hash-mapping + size: 16817 + timestamp: 1733408419340 +- pypi: https://files.pythonhosted.org/packages/44/0b/0615dbedb98f5b32a35a53290fbdc6e22306968109278d7e58df82d7a9f6/numba-0.65.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: numba + version: 0.65.1 + sha256: f80ed83774b5173abd6581cd8d2165d1d38e13d2e5c8155c0c0b421784745420 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl + name: numba + version: 0.65.1 + sha256: 1735c15c1134a5108b4d6a5c77fc0947924ea066a738dc09a52008c13df9cad3 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl + name: numba + version: 0.65.1 + sha256: 7020d74b19cdb8cff16506542fdd510756e28c5e7f3bd0b7f574f0f42272fcd9 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: numba + version: 0.65.1 + sha256: c09f49117ef255e1f1c6dad0c7a1ed39868243862a73be5706793241a3755f1b + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl + name: numba + version: 0.65.1 + sha256: df40a5028a975b9ea66f6a2a3f7abbdbd541a863070e34ed367aff21141248e4 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl + name: numba + version: 0.65.1 + sha256: 85be74c0d036842699a30058f82fb88fc5ffdc59f7615cab5792ea92914c9b62 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + name: numpy + version: 2.4.4 + sha256: 5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl + name: numpy + version: 2.4.4 + sha256: 86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl + name: numpy + version: 2.4.4 + sha256: 6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numpy + version: 2.4.4 + sha256: df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numpy + version: 2.4.4 + sha256: c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + name: numpy + version: 2.4.4 + sha256: 4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb + md5: da1b85b6a87e141f5140bb9924cecab0 + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3167099 + timestamp: 1775587756857 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + sha256: c91bf510c130a1ea1b6ff023e28bac0ccaef869446acd805e2016f69ebdc49ea + md5: 25dcccd4f80f1638428613e0d7c9b4e1 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3106008 + timestamp: 1775587972483 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + sha256: feb5815125c60f2be4a411e532db1ed1cd2d7261a6a43c54cb6ae90724e2e154 + md5: 05c7d624cff49dbd8db1ad5ba537a8a3 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 9410183 + timestamp: 1775589779763 +- pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + name: orsopy + version: 1.2.3 + sha256: 11d3ee9a1185467ba4363b24d6b98b268956ee0fb528aeff7ff106b49f363180 + requires_dist: + - pyyaml>=5.4.1 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + name: oscrypto + version: 1.3.0 + sha256: 2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085 + requires_dist: + - asn1crypto>=1.5.1 +- conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c + md5: e51f1e4089cad105b6cac64bd8166587 + depends: + - python >=3.9 + - typing_utils + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/overrides?source=hash-mapping + size: 30139 + timestamp: 1734587755455 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 + md5: 4c06a92e74452cfa53623a81592e8934 + depends: + - python >=3.8 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/packaging?source=compressed-mapping + size: 91574 + timestamp: 1777103621679 +- pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + name: paginate + version: 0.5.7 + sha256: b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 + requires_dist: + - pytest ; extra == 'dev' + - tox ; extra == 'dev' + - black ; extra == 'lint' +- pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: 5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: 61c2fd96d72b983a9891b2598f286befd4ad262161a609c92dc1652544b46b76 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl + name: pandas + version: 3.0.2 + sha256: ed72cb3f45190874eb579c64fa92d9df74e98fd63e2be7f62bce5ace0ade61df + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + name: pandas + version: 3.0.2 + sha256: 07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: dbbd4aa20ca51e63b53bbde6a0fa4254b1aaabb74d2f542df7a7959feb1d760c + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f + md5: 457c2c8c08e54905d6954e79cb5b5db9 + depends: + - python !=3.0,!=3.1,!=3.2,!=3.3 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandocfilters?source=hash-mapping + size: 11627 + timestamp: 1631603397334 +- conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + sha256: ce76d5a1fc6c7ef636cbdbf14ce2d601a1bfa0dd8d286507c1fd02546fccb94b + md5: 1a884d2b1ea21abfb73911dcdb8342e4 + depends: + - bcrypt >=3.2 + - cryptography >=3.3 + - invoke >=2.0 + - pynacl >=1.5 + - python >=3.9 + license: LGPL-2.1-or-later + license_family: LGPL + purls: + - pkg:pypi/paramiko?source=hash-mapping + size: 159896 + timestamp: 1755102147074 +- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + sha256: 611882f7944b467281c46644ffde6c5145d1a7730388bcde26e7e86819b0998e + md5: 39894c952938276405a1bd30e4ce2caf + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/parso?source=compressed-mapping + size: 82472 + timestamp: 1777722955579 +- pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + name: partd + version: 1.4.2 + sha256: 978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f + requires_dist: + - locket + - toolz + - numpy>=1.20.0 ; extra == 'complete' + - pandas>=1.3 ; extra == 'complete' + - pyzmq ; extra == 'complete' + - blosc ; extra == 'complete' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + sha256: 6eaee417d33f298db79bc7185ab1208604c0e6cf51dade34cd513c6f9db9c6f3 + md5: 11adc78451c998c0fd162584abfa3559 + depends: + - python >=3.10 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/pathspec?source=compressed-mapping + size: 56559 + timestamp: 1777271601895 +- pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + name: periodictable + version: 2.1.0 + sha256: e9155d2bf5ac10050abeff2f99096d4f04312c0c8a6bb432e28744367c5064b3 + requires_dist: + - pyparsing>=3.0.0 + - numpy + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a + md5: d0d408b1f18883a944376da5cf8101ea + depends: + - ptyprocess >=0.5 + - python >=3.9 + license: ISC + purls: + - pkg:pypi/pexpect?source=hash-mapping + size: 53561 + timestamp: 1733302019362 +- pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + name: pillow + version: 12.2.0 + sha256: 390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl + name: pillow + version: 12.2.0 + sha256: 71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: pillow + version: 12.2.0 + sha256: eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl + name: pillow + version: 12.2.0 + sha256: 6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + name: pillow + version: 12.2.0 + sha256: 56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: pillow + version: 12.2.0 + sha256: e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + name: pip + version: 26.1.1 + sha256: 99cb1c2899893b075ff56e4ed0af55669a955b49ad7fb8d8603ecdaf4ed653fb + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + sha256: 506c9330b8dc5ae98f4c32629fa59fa40e6bdd42a681c48d2f9554693dd01156 + md5: d57ef7cb7ad6b5d62cef8b9bdf1d400b + depends: + - ipykernel >=6 + - jupyter_client >=7 + - jupyter_server >=2.4 + - msgspec >=0.18 + - python >=3.10 + - returns >=0.23 + - tomli >=2 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pixi-kernel?source=hash-mapping + size: 39509 + timestamp: 1764156429044 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + sha256: 8f29915c172f1f7f4f7c9391cd5dac3ebf5d13745c8b7c8006032615246345a5 + md5: 89c0b6d1793601a2a3a3f7d2d3d8b937 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/platformdirs?source=compressed-mapping + size: 25862 + timestamp: 1775741140609 +- pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + name: plopp + version: 26.4.2 + sha256: 5cab99bb0905ce08a1d1d7d82f0f64cee7d594269ec1bd01a8a361bd14ab7bff + requires_dist: + - lazy-loader>=0.4 + - matplotlib>=3.8 + - scipp>=25.8.0 ; extra == 'scipp' + - plopp[scipp] ; extra == 'all' + - ipympl>0.8.4 ; extra == 'all' + - pythreejs>=2.4.1 ; extra == 'all' + - mpltoolbox>=24.6.0 ; extra == 'all' + - ipywidgets>=8.1.0 ; extra == 'all' + - graphviz>=0.20.3 ; extra == 'all' + - plopp[scipp] ; extra == 'test' + - graphviz>=0.20.3 ; extra == 'test' + - h5py>=3.12 ; extra == 'test' + - ipympl>=0.8.4 ; extra == 'test' + - ipywidgets>=8.1.0 ; extra == 'test' + - ipykernel>=6.26,<7 ; extra == 'test' + - mpltoolbox>=24.6.0 ; extra == 'test' + - pandas>=2.2.2 ; extra == 'test' + - plotly>=5.15.0 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'test' + - pytest>=8.0 ; extra == 'test' + - pythreejs>=2.4.1 ; extra == 'test' + - scipy>=1.10.0 ; extra == 'test' + - xarray>=2024.5.0 ; extra == 'test' + - anywidget>=0.9.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + name: plotly + version: 6.7.0 + sha256: ac8aca1c25c663a59b5b9140a549264a5badde2e057d79b8c772ae2920e32ff0 + requires_dist: + - narwhals>=1.15.1 + - packaging + - anywidget ; extra == 'dev' + - build ; extra == 'dev' + - colorcet ; extra == 'dev' + - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev' + - geopandas ; extra == 'dev' + - inflect ; extra == 'dev' + - jupyterlab ; extra == 'dev' + - kaleido>=1.1.0 ; extra == 'dev' + - numpy>=1.22 ; extra == 'dev' + - orjson ; extra == 'dev' + - pandas ; extra == 'dev' + - pdfrw ; extra == 'dev' + - pillow ; extra == 'dev' + - plotly-geo ; extra == 'dev' + - polars[timezone] ; extra == 'dev' + - pyarrow ; extra == 'dev' + - pyshp ; extra == 'dev' + - pytest ; extra == 'dev' + - pytz ; extra == 'dev' + - requests ; extra == 'dev' + - ruff==0.11.12 ; extra == 'dev' + - scikit-image ; extra == 'dev' + - scipy ; extra == 'dev' + - shapely ; extra == 'dev' + - statsmodels ; extra == 'dev' + - vaex ; python_full_version < '3.10' and extra == 'dev' + - xarray ; extra == 'dev' + - build ; extra == 'dev-build' + - jupyterlab ; extra == 'dev-build' + - pytest ; extra == 'dev-build' + - requests ; extra == 'dev-build' + - ruff==0.11.12 ; extra == 'dev-build' + - pytest ; extra == 'dev-core' + - requests ; extra == 'dev-core' + - ruff==0.11.12 ; extra == 'dev-core' + - anywidget ; extra == 'dev-optional' + - build ; extra == 'dev-optional' + - colorcet ; extra == 'dev-optional' + - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev-optional' + - geopandas ; extra == 'dev-optional' + - inflect ; extra == 'dev-optional' + - jupyterlab ; extra == 'dev-optional' + - kaleido>=1.1.0 ; extra == 'dev-optional' + - numpy>=1.22 ; extra == 'dev-optional' + - orjson ; extra == 'dev-optional' + - pandas ; extra == 'dev-optional' + - pdfrw ; extra == 'dev-optional' + - pillow ; extra == 'dev-optional' + - plotly-geo ; extra == 'dev-optional' + - polars[timezone] ; extra == 'dev-optional' + - pyarrow ; extra == 'dev-optional' + - pyshp ; extra == 'dev-optional' + - pytest ; extra == 'dev-optional' + - pytz ; extra == 'dev-optional' + - requests ; extra == 'dev-optional' + - ruff==0.11.12 ; extra == 'dev-optional' + - scikit-image ; extra == 'dev-optional' + - scipy ; extra == 'dev-optional' + - shapely ; extra == 'dev-optional' + - statsmodels ; extra == 'dev-optional' + - vaex ; python_full_version < '3.10' and extra == 'dev-optional' + - xarray ; extra == 'dev-optional' + - numpy>=1.22 ; extra == 'express' + - kaleido>=1.1.0 ; extra == 'kaleido' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + name: pluggy + version: 1.6.0 + sha256: e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + requires_dist: + - pre-commit ; extra == 'dev' + - tox ; extra == 'dev' + - pytest ; extra == 'testing' + - pytest-benchmark ; extra == 'testing' + - coverage ; extra == 'testing' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + sha256: 972e0c1c9f0b1763d482e885732baef7f9a0cbe8686f5e2c6bdd88838619a59a + md5: 7fd2e38f4e608f5ebd80f871352c5495 + depends: + - python >=3.10 + - pywin32-on-windows + - paramiko + - importlib_resources + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/plumbum?source=hash-mapping + size: 103911 + timestamp: 1761911487086 +- pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + name: ply + version: '3.11' + sha256: 096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce +- pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + name: pooch + version: 1.9.0 + sha256: f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b + requires_dist: + - platformdirs>=2.5.0 + - packaging>=20.0 + - requests>=2.19.0 + - tqdm>=4.41.0,<5.0.0 ; extra == 'progress' + - paramiko>=2.7.0 ; extra == 'sftp' + - xxhash>=1.4.3 ; extra == 'xxhash' + - pytest-httpserver ; extra == 'test' + - pytest-localftpserver ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + name: pre-commit + version: 4.6.0 + sha256: e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b + requires_dist: + - cfgv>=2.0.0 + - identify>=1.0.0 + - nodeenv>=0.11.1 + - pyyaml>=5.1 + - virtualenv>=20.10.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + name: prettytable + version: 3.17.0 + sha256: aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 + requires_dist: + - wcwidth + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-lazy-fixtures ; extra == 'tests' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + sha256: 4d7ec90d4f9c1f3b4a50623fefe4ebba69f651b102b373f7c0e9dbbfa43d495c + md5: a11ab1f31af799dd93c3a39881528884 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/prometheus-client?source=compressed-mapping + size: 57113 + timestamp: 1775771465170 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + sha256: ebc1bb62ac612af6d40667da266ff723662394c0ca78935340a5b5c14831227b + md5: d17ae9db4dc594267181bd199bf9a551 + depends: + - python >=3.9 + - wcwidth + constrains: + - prompt_toolkit 3.0.51 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/prompt-toolkit?source=hash-mapping + size: 271841 + timestamp: 1744724188108 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + sha256: 936189f0373836c1c77cd2d6e71ba1e583e2d3920bf6d015e96ee2d729b5e543 + md5: 1e61ab85dd7c60e5e73d853ea035dc29 + depends: + - prompt-toolkit >=3.0.51,<3.0.52.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7182 + timestamp: 1744724189376 +- pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: propcache + version: 0.4.1 + sha256: fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: 6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: propcache + version: 0.4.1 + sha256: d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + name: propcache + version: 0.4.1 + sha256: 364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + name: propcache + version: 0.4.1 + sha256: 381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda + sha256: 8d9325af538a8f56013e42bbb91a4dc6935aece34476e20bafacf6007b571e86 + md5: 2ed8f6fe8b51d8e19f7621941f7bb95f + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 231786 + timestamp: 1769678156460 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + sha256: f19fd682d874689dfde20bf46d7ec1a28084af34583e0405685981363af47c91 + md5: 25fe6e02c2083497b3239e21b49d8093 + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 228663 + timestamp: 1769678153829 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda + sha256: 2b774e8f4ccaac8783d1908f281e4bb20b7036d6708dc913ee7811b070f5b4b5 + md5: 7cff50265141513c960f00ba586780ea + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 245203 + timestamp: 1769678306347 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + sha256: 1d2a6039fb71d61134b1d6816202529f2f6286c83b59bc1491fd288f5c08046e + md5: ba2d89e51a855963c767648f44c03871 + depends: + - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 242596 + timestamp: 1769678288893 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda + sha256: 32da17824abadd1f5b46faedfa4964c7b1817b11887c2e8bb4e48628da51b93a + md5: fd968cdacc7967efd0ff5ef1805b812c + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 249478 + timestamp: 1769678166841 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + sha256: 3ec3373748f83069bef93b540de416e637ee30231b222d5df8f712e93f2f9195 + md5: 761b299a6289c77459defea3563f8fc0 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 246062 + timestamp: 1769678176886 +- conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + sha256: a7713dfe30faf17508ec359e0bc7e0983f5d94682492469bd462cdaae9c64d83 + md5: 7d9daffbb8d8e0af0f769dbbcd173a54 + depends: + - python >=3.9 + license: ISC + purls: + - pkg:pypi/ptyprocess?source=hash-mapping + size: 19457 + timestamp: 1733302371990 +- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 + md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pure-eval?source=hash-mapping + size: 16668 + timestamp: 1733569518868 +- pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + name: py + version: 1.11.0 + sha256: 607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + name: py3dmol + version: 2.5.4 + sha256: 32806726b5310524a2b5bfee320737f7feef635cafc945c991062806daa9e43a + requires_dist: + - ipython ; extra == 'ipython' +- pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + name: pycairo + version: 1.29.0 + sha256: 91114e4b3fbf4287c2b0788f83e1f566ce031bda49cf1c3c3c19c3e986e95c38 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl + name: pycairo + version: 1.29.0 + sha256: 3391532db03f9601c1cee9ebfa15b7d1db183c6020f3e75c1348cee16825934f + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: pycifrw + version: 5.0.1 + sha256: 65a90ee34e46e6be20834493382585277d12daaa8d1a145cb158c163b3d9fc1c + requires_dist: + - prettytable + - ply + - numpy +- pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl + name: pycifrw + version: 5.0.1 + sha256: e9ad2fdb4fca6398ed5ae50c19908bf6238434893b68d0125bda79a54a03d708 + requires_dist: + - prettytable + - ply + - numpy +- pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl + name: pycifrw + version: 5.0.1 + sha256: 8632df76b99932408ab432e09b30aa9a6c390df884a5f34f1e1f76201e625156 + requires_dist: + - prettytable + - ply + - numpy +- pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + name: pycifstar + version: 0.3.0 + sha256: 5892fdf16c83372ee5f32557127d5f36e14b0bbe520883a4e2e70365382f70ed +- pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + name: pycodestyle + version: 2.14.0 + sha256: dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 + md5: 12c566707c80111f9799308d9e265aef + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pycparser?source=hash-mapping + size: 110100 + timestamp: 1733195786147 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f + md5: 729843edafc0899b3348bd3f19525b9d + depends: + - typing-inspection >=0.4.2 + - typing_extensions >=4.14.1 + - python >=3.10 + - annotated-types >=0.6.0 + - pydantic-core ==2.46.4 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic?source=compressed-mapping + size: 346511 + timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda + sha256: ac3faa31154a85f4b1a4618957b4a06623ff2c6a85f8eac20efe9dbac5757d91 + md5: b6cfa054aec29586d383f9e666bd0e9a + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.11.* *_cp311 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1884122 + timestamp: 1778084220486 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + sha256: d6705962afa2655cc22edcd075ce1f7e67c4407c005137d6d63c0dc5eaa76f47 + md5: ef0f9efec6ec28b17e22f787c7672c67 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.13.* *_cp313 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1893749 + timestamp: 1778084222642 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda + sha256: 194e8872dcda301703c8f1427e480fee6421e3901803ffc863b68eb886372eaf + md5: 80d6864b30e0697b652a9bd580b2d351 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - __osx >=11.0 + - python 3.11.* *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1730463 + timestamp: 1778084304998 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + sha256: 5bcc20f2c21d8a20d8f2821caf31d8c0ef2fa3bcdaf7a9bdce62e37be819f1d7 + md5: 32bb0d4dbb1be2064c06248a1190aa96 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - python 3.13.* *_cp313 + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1720475 + timestamp: 1778084300413 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda + sha256: 4cf860418a6a1a678bcc23bc29a83f4f0916682fd6ab1ff209b4e5ee3dc5e15f + md5: 85efdb748cbec9210e718c4a8860749c + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1898998 + timestamp: 1778084255268 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + sha256: 6466b7e441adb71e29308de2a87c9787d5d0100601ede2d02ed4f85c251699d6 + md5: 9981bc46be6341306a5473b290b2f366 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1888029 + timestamp: 1778084253466 +- pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + name: pydoclint + version: 0.8.3 + sha256: 5fc9b82d0d515afce0908cb70e8ff695a68b19042785c248c4f227ad66b4a164 + requires_dist: + - click>=8.1.0 + - docstring-parser-fork>=0.0.12 + - tomli>=2.0.1 ; python_full_version < '3.11' + - flake8>=4 ; extra == 'flake8' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 + md5: 16c18772b340887160c79a6acc022db0 + depends: + - python >=3.10 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/pygments?source=compressed-mapping + size: 893031 + timestamp: 1774796815820 +- pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + name: pyhanko + version: 0.35.1 + sha256: 57c085f29d7f87334be2a5fbd38a1ca3c987f40f51aea38bde628497d6d9ef2e + requires_dist: + - asn1crypto>=1.5.1 + - tzlocal>=4.3 + - pyhanko-certvalidator>=0.31.1,<0.32 + - requests>=2.31.0 + - pyyaml>=6.0 + - cryptography>=48.0.0 + - lxml>=5.4.0 + - fonttools>=4.33.3 ; extra == 'opentype' + - uharfbuzz>=0.25.0,<0.55.0 ; extra == 'opentype' + - qrcode>=7.3.1 ; extra == 'qr' + - pillow>=7.2.0 ; extra == 'image-support' + - python-barcode==0.16.1 ; extra == 'image-support' + - python-pkcs11~=0.9.3 ; extra == 'pkcs11' + - aiohttp>=3.9,<3.14 ; extra == 'async-http' + - xsdata>=24.4,<27.0 ; extra == 'etsi' + - signxml>=4.2.0 ; extra == 'etsi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + name: pyhanko-certvalidator + version: 0.31.1 + sha256: 0aabe25b536ed555f3b18e5eb2c62ff46adeff9d15e27f0c9d5d81952d956f45 + requires_dist: + - asn1crypto>=1.5.1 + - oscrypto>=1.1.0 + - cryptography>=48.0.0 + - uritools>=3.0.1 + - requests>=2.31.0 + - aiohttp>=3.9,<3.14 ; extra == 'async-http' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + name: pymdown-extensions + version: 10.21.2 + sha256: 5c0fd2a2bea14eb39af8ff284f1066d898ab2187d81b889b75d46d4348c01638 + requires_dist: + - markdown>=3.6 + - pyyaml + - pygments>=2.19.1 ; extra == 'extra' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda + sha256: 4b89f502dc58df0abb27d4677ca4b0ef5230f5c28e24b80eef3dc0c9c968e225 + md5: fb7e00fed4fddee97e6cf0bd3ae9a27e + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=1.4.1 + - libgcc >=14 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1151915 + timestamp: 1772171237221 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + sha256: 51e80a7bef95025ad47a92acb69ee0e78f01e107655c86fe76abcde2ac688166 + md5: c4426edfc5514a2c9be6871557bce52b + depends: + - __glibc >=2.17,<3.0.a0 + - cffi >=1.4.1 + - libgcc >=14 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1191901 + timestamp: 1772171244923 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda + sha256: 503b3a2543577f2fb70ddc44113a4da7ecdfdfb2bf51ecd1203adcb93e7257df + md5: 64d4dd58b1eb87d7e6ba084c7dc9259b + depends: + - __osx >=11.0 + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1188895 + timestamp: 1772171487639 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + sha256: ef6ab85953ebf81b3b0c6d0b6377eb1a318b07823e76d2c8e850365e60d9ca5c + md5: fca94b9ddea6d5c63ccb6b5ad6d8e232 + depends: + - __osx >=11.0 + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1192924 + timestamp: 1772171603602 +- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda + sha256: cd35ad681895b45f578bac8fd8dafc87116c2db42489dda9bef76ff3518bbc73 + md5: e2197089006b3cda7e03c7a51fa7050e + depends: + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - six + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1147862 + timestamp: 1772171327674 +- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + sha256: 0960e727d0bd70e07bca0c049c4c4afa0b41bcea050135db49f54c1c0c02ed7f + md5: 99b7617a643bed6a403fc908c1e167f0 + depends: + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - six + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1186552 + timestamp: 1772171311072 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda + sha256: f6dced0ea4f220abc1278f6217e22ca1c631f6154dd086b0a7a2866589d6b78c + md5: 812e22c5c7859e719ec225ece0c6f2c1 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - setuptools + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-core?source=hash-mapping + size: 481434 + timestamp: 1763151508974 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + sha256: 307ca29ebf2317bd2561639b1ee0290fd8c03c3450fa302b9f9437d8df6a5280 + md5: 31a0a72f3466682d0ea2ebcbd7d319b8 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - setuptools + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-core?source=hash-mapping + size: 481508 + timestamp: 1763152124940 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda + sha256: 67e209a5e9ebaf08aa36e2a4b9139ff91a7ecee7c17408d0a3a1ea1dc3a67681 + md5: b215a767b5ef6f16347cacebc409e66b + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pyobjc-core 12.1.* + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping + size: 383445 + timestamp: 1763160541362 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + sha256: 194e188d8119befc952d04157079733e2041a7a502d50340ddde632658799fdc + md5: a6d28c8fc266a3d3c3dae183e25c4d31 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pyobjc-core 12.1.* + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping + size: 376136 + timestamp: 1763160678792 +- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + name: pyparsing + version: 3.3.2 + sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d + requires_dist: + - railroad-diagrams ; extra == 'diagrams' + - jinja2 ; extra == 'diagrams' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + name: pypdf + version: 6.10.2 + sha256: aa53be9826655b51c96741e5d7983ca224d898ac0a77896e64636810517624aa + requires_dist: + - typing-extensions>=4.0 ; python_full_version < '3.11' + - cryptography ; extra == 'crypto' + - pycryptodome ; extra == 'cryptodome' + - flit ; extra == 'dev' + - pip-tools ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-socket ; extra == 'dev' + - pytest-timeout ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - wheel ; extra == 'dev' + - myst-parser ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - cryptography ; extra == 'full' + - pillow>=8.0.0 ; extra == 'full' + - pillow>=8.0.0 ; extra == 'image' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + name: pyproject-hooks + version: 1.2.0 + sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca + md5: e2fd202833c4a981ce8a65974fe4abd1 + depends: + - __win + - python >=3.9 + - win_inet_pton + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21784 + timestamp: 1733217448189 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 + md5: 461219d1a5bd61342293efa2c0c90eac + depends: + - __unix + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21085 + timestamp: 1733217331982 +- pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + name: pytest + version: 9.0.3 + sha256: 2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 + requires_dist: + - colorama>=0.4 ; sys_platform == 'win32' + - exceptiongroup>=1 ; python_full_version < '3.11' + - iniconfig>=1.0.1 + - packaging>=22 + - pluggy>=1.5,<2 + - pygments>=2.7.2 + - tomli>=1 ; python_full_version < '3.11' + - argcomplete ; extra == 'dev' + - attrs>=19.2 ; extra == 'dev' + - hypothesis>=3.56 ; extra == 'dev' + - mock ; extra == 'dev' + - requests ; extra == 'dev' + - setuptools ; extra == 'dev' + - xmlschema ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + name: pytest-cov + version: 7.1.0 + sha256: a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 + requires_dist: + - coverage[toml]>=7.10.6 + - pluggy>=1.2 + - pytest>=7 + - process-tests ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - virtualenv ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + name: pytest-xdist + version: 3.8.0 + sha256: 202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 + requires_dist: + - execnet>=2.1 + - pytest>=7.0.0 + - filelock ; extra == 'testing' + - psutil>=3.0 ; extra == 'psutil' + - setproctitle ; extra == 'setproctitle' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda + sha256: bf6a32c69889d38482436a786bea32276756cedf0e9805cc856ffd088e8d00f0 + md5: a5ebcefec0c12a333bcd6d7bf3bddc1f + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libnsl >=2.0.1,<2.1.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libxcrypt >=4.4.36 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 30949404 + timestamp: 1772730362552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + build_number: 100 + sha256: 7f77eb57648f545c1f58e10035d0d9d66b0a0efb7c4b58d3ed89ec7269afdde1 + md5: 05051be49267378d2fcd12931e319ac3 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libuuid >=2.42,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + license: Python-2.0 + purls: [] + size: 37358322 + timestamp: 1775614712638 + python_site_packages_path: lib/python3.13/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda + sha256: 9a846065863925b2562126a5c6fecd7a972e84aaa4de9e686ad3715ca506acfa + md5: 49c7d96c58b969585cf09fb01d74e08e + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 14753109 + timestamp: 1772730203101 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + build_number: 100 + sha256: d0fffc5fde21d1ae350da545dfb9e115a8c53bed8a9c5761f9efd4a5581853c1 + md5: 9991a930e81d3873eba7a299ba783ec4 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + license: Python-2.0 + purls: [] + size: 12966447 + timestamp: 1775615694085 + python_site_packages_path: lib/python3.13/site-packages +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda + sha256: a1f1031088ce69bc99c82b95980c1f54e16cbd5c21f042e9c1ea25745a8fc813 + md5: d09dbf470b41bca48cbe6a78ba1e009b + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 18416208 + timestamp: 1772728847666 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + build_number: 100 + sha256: b8108d7f83f71fb15fbb4a263406c2065a8990b3d7eba2cbd7a3075b9a6392ba + md5: 7065f7067762c4c2bda1912f18d16239 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Python-2.0 + purls: [] + size: 16618694 + timestamp: 1775613654892 + python_site_packages_path: Lib/site-packages +- pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: python-bidi + version: 0.6.9 + sha256: 29e40e02bf2bddec225730eb3ba9f4ca948dced9877358458b74d7a447d936ac + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + name: python-bidi + version: 0.6.9 + sha256: 001c1769893fd859216b0dc39dd4679c7260bf292c3637b727a928402a254322 + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl + name: python-bidi + version: 0.6.9 + sha256: c3554a3cb9b95e503bc348a8c461b330bf1812c500f51bc9bbd789544fc4a8aa + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: python-bidi + version: 0.6.9 + sha256: 6cf6941062f0589291a396b3d81636b7e35a99105098bc147c48e077c0fb4b45 + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl + name: python-bidi + version: 0.6.9 + sha256: c3e4445f0fd1e2c16d3efdb28622a38f57ab4b971eb47803a334be477cee173e + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl + name: python-bidi + version: 0.6.9 + sha256: be28092eef062fad59e7e0402bf2c1db797ccadedd866a53bbd7ddb97e42cac1 + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 + md5: 5b8d21249ff20967101ffa321cab24e8 + depends: + - python >=3.9 + - six >=1.5 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/python-dateutil?source=hash-mapping + size: 233310 + timestamp: 1751104122689 +- pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + name: python-discovery + version: 1.3.0 + sha256: 441d9ced3dfce36e113beb35ca302c71c7ef06f3c0f9c227a0b9bb3bd49b9e9f + requires_dist: + - filelock>=3.15.4 + - platformdirs>=4.3.6,<5 + - furo>=2025.12.19 ; extra == 'docs' + - sphinx-autodoc-typehints>=3.6.3 ; extra == 'docs' + - sphinx>=9.1 ; extra == 'docs' + - sphinxcontrib-mermaid>=2 ; extra == 'docs' + - covdefaults>=2.3 ; extra == 'testing' + - coverage>=7.5.4 ; extra == 'testing' + - pytest-mock>=3.14 ; extra == 'testing' + - pytest>=8.3.5 ; extra == 'testing' + - setuptools>=75.1 ; extra == 'testing' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + name: python-engineio + version: 4.13.1 + sha256: f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399 + requires_dist: + - simple-websocket>=0.10.0 + - requests>=2.21.0 ; extra == 'client' + - websocket-client>=0.54.0 ; extra == 'client' + - aiohttp>=3.11 ; extra == 'asyncio-client' + - tox ; extra == 'dev' + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + sha256: df9aa74e9e28e8d1309274648aac08ec447a92512c33f61a8de0afa9ce32ebe8 + md5: 23029aae904a2ba587daba708208012f + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fastjsonschema?source=hash-mapping + size: 244628 + timestamp: 1755304154927 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + sha256: b2e51d83e5ebeb7e9fde1cde822a60e8564cc9dabd786ad853056afbf708a466 + md5: fd00e4b24ea88093c93f5c9bad27b52f + depends: + - cpython 3.13.13.* + - python_abi * *_cp313 + license: Python-2.0 + purls: [] + size: 48536 + timestamp: 1775613791711 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + sha256: 1c55116c22512cef7b01d55ae49697707f2c1fd829407183c19817e2d300fd8d + md5: 1cd2f3e885162ee1366312bd1b1677fd + depends: + - python >=3.10 + - typing_extensions + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/python-json-logger?source=compressed-mapping + size: 18969 + timestamp: 1777318679482 +- pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + name: python-socketio + version: 5.16.1 + sha256: a3eb1702e92aa2f2b5d3ba00261b61f062cce51f1cfb6900bf3ab4d1934d2d35 + requires_dist: + - bidict>=0.21.0 + - python-engineio>=4.11.0 + - requests>=2.21.0 ; extra == 'client' + - websocket-client>=0.54.0 ; extra == 'client' + - aiohttp>=3.4 ; extra == 'asyncio-client' + - tox ; extra == 'dev' + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + sha256: e943f9c15a6bdba2e1b9f423ab913b3f6b02197b0ef9f8e6b7464d78b59965b9 + md5: f6ad7450fc21e00ecc23812baed6d2e4 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tzdata?source=compressed-mapping + size: 146639 + timestamp: 1777068997932 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda + build_number: 8 + sha256: fddf123692aa4b1fc48f0471e346400d9852d96eeed77dbfdd746fa50a8ff894 + md5: 8fcb6b0e2161850556231336dae58358 + constrains: + - python 3.11.* *_cpython + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7003 + timestamp: 1752805919375 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + build_number: 8 + sha256: 210bffe7b121e651419cb196a2a63687b087497595c9be9d20ebe97dd06060a7 + md5: 94305520c52a4aa3f6c2b1ff6008d9f8 + constrains: + - python 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7002 + timestamp: 1752805902938 +- pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + name: pythreejs + version: 2.4.2 + sha256: 8418807163ad91f4df53b58c4e991b26214852a1236f28f1afeaadf99d095818 + requires_dist: + - ipywidgets>=7.2.1 + - ipydatawidgets>=1.1.1 + - numpy + - traitlets + - sphinx>=1.5 ; extra == 'docs' + - nbsphinx>=0.2.13 ; extra == 'docs' + - nbsphinx-link ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - scipy ; extra == 'examples' + - matplotlib ; extra == 'examples' + - scikit-image ; extra == 'examples' + - ipywebrtc ; extra == 'examples' + - nbval ; extra == 'test' + - pytest-check-links ; extra == 'test' + - numpy>=1.14 ; extra == 'test' + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda + sha256: e3ef7e0cc53111ab81b8a9dd3eabc1374d7420d4c9fce3c8631e73310203ad55 + md5: c1cfe9f5d8e278cc4d2d4c7b0126634d + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 6729388 + timestamp: 1756487145061 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + sha256: 87eaeb79b5961e0f216aa840bc35d5f0b9b123acffaecc4fda4de48891901f20 + md5: 1ce4f826332dca56c76a5b0cc89fb19e + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 6695114 + timestamp: 1756487139550 +- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + sha256: 09803b75cccc16d8586d2f41ea890658d165f4afc359973fa1c7904a2c140eae + md5: 91733394059b880d9cc0d010c20abda0 + depends: + - python >=2.7 + - pywin32 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5282 + timestamp: 1646866839398 +- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + sha256: 6502696aaef571913b22a808b15c185bd8ea4aabb952685deb29e6a6765761cb + md5: 2807a0becd1d986fe1ef9b7f8135f215 + depends: + - __unix + - python >=2.7 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4856 + timestamp: 1646866525560 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda + sha256: b1f6b3a907e36f7af486faf3892f47fab42993c13c934cc19855bbae227f2b18 + md5: e5dd9afed138ff193d4593f1b15a388b + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - winpty + license: MIT + license_family: MIT + purls: + - pkg:pypi/pywinpty?source=hash-mapping + size: 215911 + timestamp: 1759557817579 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + sha256: d34a7cd0a4a7dc79662cb6005e01d630245d9a942e359eb4d94b2fb464ed2552 + md5: 8f01ed27e2baa455e753301218e054fd + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - winpty + license: MIT + license_family: MIT + purls: + - pkg:pypi/pywinpty?source=hash-mapping + size: 216075 + timestamp: 1759556799508 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda + sha256: c9a6cd2c290d7c3d2b30ea34a0ccda30f770e8ddb2937871f2c404faf60d0050 + md5: a24add9a3bababee946f3bc1c829acfe + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 206190 + timestamp: 1770223702917 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + sha256: ef7df29b38ef04ec67a8888a4aa039973eaa377e8c4b59a7be0a1c50cd7e4ac6 + md5: f256753e840c3cd3766488c9437a8f8b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=compressed-mapping + size: 201616 + timestamp: 1770223543730 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda + sha256: 984e73d7957460689e10533059de8adb38a308853d298900a37acc58edd84cec + md5: e4b908da7cd496b3fa6798c0f60a2a19 + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 192948 + timestamp: 1770223655988 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + sha256: 950725516f67c9691d81bb8dde8419581c5332c5da3da10c9ba8cbb1698b825d + md5: 5d0c8b92128c93027632ca8f8dc1190f + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 188763 + timestamp: 1770224094408 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda + sha256: 301c3ba100d25cd5ae37895988ee3ab986210d4d972aa58efed948fbe857773d + md5: a0153c033dc55203e11d1cac8f6a9cf2 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 187108 + timestamp: 1770223467913 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + sha256: dfaed50de8ee72a51096163b87631921688851001e38c78a841eba1ae8b35889 + md5: c1bdb8dd255c79fb9c428ad25cc6ee54 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 180992 + timestamp: 1770223457761 +- pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + name: pyyaml-env-tag + version: '1.1' + sha256: 17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 + requires_dist: + - pyyaml + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda + sha256: 4137226663b353919396f8cf239971cfa54107cd077cf3b65e979ba3e1f8a037 + md5: 759edfe34f07c5c4565b6c5ec0c7fb17 + depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - zeromq >=4.3.5,<4.4.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 383627 + timestamp: 1771716979818 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + noarch: python + sha256: be66c1f85c3b48137200d62c12d918f4f8ad329423daef04fed292818efd3c28 + md5: 082985717303dab433c976986c674b35 + depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - zeromq >=4.3.5,<4.4.0a0 + - _python_abi3_support 1.* + - cpython >=3.12 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 211567 + timestamp: 1771716961404 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda + sha256: c5d65e1192241d764a68eb0e95ef3ec4800a7e8584260aa2bdcfad0a2d769609 + md5: 9648524ed194922a084f0c2c2c2ada6a + depends: + - python + - __osx >=11.0 + - python 3.11.* *_cpython + - libcxx >=19 + - zeromq >=4.3.5,<4.4.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 359869 + timestamp: 1771717160649 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + noarch: python + sha256: 2f31f799a46ed75518fae0be75ecc8a1b84360dbfd55096bc2fe8bd9c797e772 + md5: 2f6b79700452ef1e91f45a99ab8ffe5a + depends: + - python + - libcxx >=19 + - __osx >=11.0 + - _python_abi3_support 1.* + - cpython >=3.12 + - zeromq >=4.3.5,<4.4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 191641 + timestamp: 1771717073430 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda + sha256: d37e831618e8df0506d32e16820adab550b74b36d039da753f7543bb967b700d + md5: 0ad824e928af5d6200a97649d810ab2b + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + - zeromq >=4.3.5,<4.3.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 363314 + timestamp: 1771716977369 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + noarch: python + sha256: d84bcc19a945ca03d1fd794be3e9896ab6afc9f691d58d9c2da514abe584d4df + md5: eb1ec67a70b4d479f7dd76e6c8fe7575 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zeromq >=4.3.5,<4.3.6.0a0 + - _python_abi3_support 1.* + - cpython >=3.12 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 183235 + timestamp: 1771716967192 +- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + sha256: 0604c6dff3af5f53e34fceb985395d08287137f220450108a795bcd1959caf14 + md5: 34fa231b5c5927684b03bb296bb94ddc + depends: + - prompt_toolkit >=2.0,<4.0 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/questionary?source=hash-mapping + size: 31257 + timestamp: 1757356458097 +- pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + name: radon + version: 6.0.1 + sha256: 632cc032364a6f8bb1010a2f6a12d0f14bc7e5ede76585ef29dc0cecf4cd8859 + requires_dist: + - mando>=0.6,<0.8 + - colorama==0.4.1 ; python_full_version < '3.5' + - colorama>=0.4.1 ; python_full_version >= '3.5' + - tomli>=2.0.1 ; extra == 'toml' +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 + depends: + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 313930 + timestamp: 1765813902568 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 + md5: 870293df500ca7e18bedefa5838a22ab + depends: + - attrs >=22.2.0 + - python >=3.10 + - rpds-py >=0.7.0 + - typing_extensions >=4.4.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/referencing?source=hash-mapping + size: 51788 + timestamp: 1760379115194 +- pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + name: refl1d + version: 1.0.1 + sha256: 8cc52121790df465e3a659d0fb0298f2501256c6f2d7fca26085927297112eb1 + requires_dist: + - bumps==1.0.4 + - matplotlib + - numba + - numpy + - periodictable + - scipy + - orsopy + - ipython ; extra == 'dev' + - matplotlib ; extra == 'dev' + - nbsphinx ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydantic ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - sphinx<8.2 ; extra == 'dev' + - versioningit ; extra == 'dev' + - wxpython ; extra == 'full' + - ipython ; extra == 'full' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + name: refnx + version: 0.1.63 + sha256: 3a12accac6e469fd2c0ef49357301299f6b2e4a9ecdfdfb90b592dad59214eb9 + requires_dist: + - numpy>=2.0 + - scipy + - orsopy + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - traitlets ; extra == 'all' + - matplotlib ; extra == 'all' + - xlrd ; extra == 'all' + - h5py ; extra == 'all' + - jupyter ; extra == 'all' + - tqdm ; extra == 'all' + - pymc ; extra == 'all' + - pytensor ; extra == 'all' + - attrs ; extra == 'all' + - pandas ; extra == 'all' + - pyparsing ; extra == 'all' + - periodictable ; extra == 'all' + - pyqt6 ; extra == 'all' + - qtpy ; extra == 'all' + - corner ; extra == 'all' + - numba ; extra == 'all' + - pytest ; extra == 'test' + - uncertainties ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + name: refnx + version: 0.1.63 + sha256: 9bc88eba956e97892805d2fb18a7268780f943c5d74feb5d1c58f5ae90699fa2 + requires_dist: + - numpy>=2.0 + - scipy + - orsopy + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - traitlets ; extra == 'all' + - matplotlib ; extra == 'all' + - xlrd ; extra == 'all' + - h5py ; extra == 'all' + - jupyter ; extra == 'all' + - tqdm ; extra == 'all' + - pymc ; extra == 'all' + - pytensor ; extra == 'all' + - attrs ; extra == 'all' + - pandas ; extra == 'all' + - pyparsing ; extra == 'all' + - periodictable ; extra == 'all' + - pyqt6 ; extra == 'all' + - qtpy ; extra == 'all' + - corner ; extra == 'all' + - numba ; extra == 'all' + - pytest ; extra == 'test' + - uncertainties ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: refnx + version: 0.1.63 + sha256: 4f397b0d6e18ac1bb793372ec92c9f4a122383387a706dea456df5a2c90dff5e + requires_dist: + - numpy>=2.0 + - scipy + - orsopy + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - traitlets ; extra == 'all' + - matplotlib ; extra == 'all' + - xlrd ; extra == 'all' + - h5py ; extra == 'all' + - jupyter ; extra == 'all' + - tqdm ; extra == 'all' + - pymc ; extra == 'all' + - pytensor ; extra == 'all' + - attrs ; extra == 'all' + - pandas ; extra == 'all' + - pyparsing ; extra == 'all' + - periodictable ; extra == 'all' + - pyqt6 ; extra == 'all' + - qtpy ; extra == 'all' + - corner ; extra == 'all' + - numba ; extra == 'all' + - pytest ; extra == 'test' + - uncertainties ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + name: reportlab + version: 4.5.0 + sha256: b8cc8996947d84e805368b47b2376070966f091d029351a0d8a1f238984c2c7f + requires_dist: + - pillow>=9.0.0 + - charset-normalizer + - rl-accel>=0.9.0,<1.1 ; extra == 'accel' + - rl-renderpm>=4.0.3,<4.1 ; extra == 'renderpm' + - rlpycairo>=0.2.0,<1 ; extra == 'pycairo' + - freetype-py>=2.3.0,<2.4 ; extra == 'pycairo' + - rlbidi ; extra == 'bidi' + - uharfbuzz ; extra == 'shaping' + requires_python: '>=3.9,<4' +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + sha256: 7f2c24dd3bd3c104a1d2c9a10ead5ed6758b0976b74f972cfe9c19884ccc4241 + md5: 9659f587a8ceacc21864260acd02fc67 + depends: + - python >=3.10 + - certifi >=2023.5.7 + - charset-normalizer >=2,<4 + - idna >=2.5,<4 + - urllib3 >=1.26,<3 + - python + constrains: + - chardet >=3.0.2,<8 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/requests?source=compressed-mapping + size: 63728 + timestamp: 1777030058920 +- conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + sha256: 3b45efeae771f1a20307b36ecdb3a8911a89c05382836b50c62b0a99d8d3dfd8 + md5: da94ff04d97ec5efc42cbe5da3c43a84 + depends: + - python >=3.11 + - typing_extensions >=4.0,<5.0 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/returns?source=hash-mapping + size: 100559 + timestamp: 1776176903101 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 + md5: 36de09a8d3e5d5e6f4ee63af49e59706 + depends: + - python >=3.9 + - six + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3339-validator?source=hash-mapping + size: 10209 + timestamp: 1733600040800 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 + md5: 912a71cc01012ee38e6b90ddd561e36f + depends: + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3986-validator?source=hash-mapping + size: 7818 + timestamp: 1598024297745 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 + md5: 7234f99325263a5af6d4cd195035e8f2 + depends: + - python >=3.9 + - lark >=1.2.2 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3987-syntax?source=hash-mapping + size: 22913 + timestamp: 1752876729969 +- pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + name: rich + version: 15.0.0 + sha256: 33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb + requires_dist: + - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' + - markdown-it-py>=2.2.0 + - pygments>=2.13.0,<3.0.0 + requires_python: '>=3.9.0' +- pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + name: rlpycairo + version: 0.4.0 + sha256: 3ce83825d5761c03bc3571c7db12a336ad51417e63189e3512d11b8922576aa9 + requires_dist: + - pycairo>=1.20.0 + - freetype-py>=2.3 + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda + sha256: bf5e6197fb08b8c6e421ca0126e966b7c3ae62b84d7b98523356b4fd5ae6f8ae + md5: 3893f7b40738f9fe87510cb4468cdda5 + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.11.* *_cp311 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 383153 + timestamp: 1764543197251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + sha256: 076d26e51c62c8ecfca6eb19e3c1febdd7632df1990a7aa53da5df5e54482b1c + md5: 779e3307a0299518713765b83a36f4b1 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.13.* *_cp313 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 383230 + timestamp: 1764543223529 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda + sha256: 15873755f078583cea046f7ca7fc0d5348d1f29a16a30b73bdb53dd62f2ba379 + md5: 4408829b022e8e0d19365c0c00be00c4 + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 357600 + timestamp: 1764543142990 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + sha256: db63344f91e8bfe77703c6764aa9eeafb44d165e286053214722814eabda0264 + md5: 190c2d0d4e98ec97df48cdb74caf44d8 + depends: + - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 358961 + timestamp: 1764543165314 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda + sha256: 6edeab1412def450e72f0e96a5d8bb31a2a0b4e56624699c916d3bafd4d9b475 + md5: 43ab63451a9df29f2c499da524665de9 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 241288 + timestamp: 1764543026991 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + sha256: 27bd383787c0df7a0a926b11014fd692d60d557398dcf1d50c55aa2378507114 + md5: 58ae648b12cfa6df3923b5fd219931cb + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 243419 + timestamp: 1764543047271 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + noarch: python + sha256: 98c771464ed93a2733bae460c39cfa9640feb20972d2e651b44e85db296942eb + md5: 3c8f229055ad244fa3a97c6c45b77099 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 9266480 + timestamp: 1778119386343 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + noarch: python + sha256: 91992a557456cbe9980e8ffb0f0d1200f65f741adeefc7ecf568d1935690a7bc + md5: 7151a0851207b88c0031f388a7825e9b + depends: + - python + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 8485007 + timestamp: 1778119519471 +- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + noarch: python + sha256: 9b47c39449fd0102315bb62bd632707a754d32cf6c6f08d2a9c74b0a476f2282 + md5: 2db0d3419f3e6fc05516da561f81cda5 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 9719930 + timestamp: 1778119435755 +- pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + name: sciline + version: 25.11.1 + sha256: 13c378287b8157e819b9b67d7e973c65bc6bdc545a3602d18204c365b0c336f9 + requires_dist: + - cyclebane>=24.6.0 + - pytest ; extra == 'test' + - pytest-randomly>=3 ; extra == 'test' + - dask ; extra == 'test' + - graphviz ; extra == 'test' + - jsonschema ; extra == 'test' + - numpy ; extra == 'test' + - pandas ; extra == 'test' + - pydantic ; extra == 'test' + - rich ; extra == 'test' + - rich ; extra == 'progress' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 26.3.1 + sha256: 993706e7c31f0317be2db5f528f9142ba67b2e52d7af174fcad195f702e1d6c7 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + name: scipp + version: 26.3.1 + sha256: 03c6dbf8936a2ed62587c5abe8ab5266a5098834a0709321ce799bd1328eb3e6 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl + name: scipp + version: 26.3.1 + sha256: 67d275fc83b062053df9aa7ce3af4d2205109c2bc3ab22467bcd73ceb0a83df2 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + name: scipp + version: 26.3.1 + sha256: 8dfe8adedb5cba05acaaea15e3b6fe1820ac2f497e87c1e581ba4be9d82c53bb + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 26.3.1 + sha256: ab5859a24b3150b588dd2c67e68b0c7f07c9444eae501f3b6326d6b4a34cbf10 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + name: scipp + version: 26.3.1 + sha256: 37877cf07b4f54f224d5465c265d6a1e591d605d0c23dd350a4b48d95c26ab7b + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + name: scippneutron + version: 26.4.1 + sha256: 3b9865ebdb7923eb25739b7cda624555d45275341000f099c1dcf371b1dd7e35 + requires_dist: + - python-dateutil>=2.8 + - email-validator>=2 + - h5py>=3.12 + - lazy-loader>=0.4 + - mpltoolbox>=24.6.0 + - numpy>=1.20 + - plopp>=26.4.1 + - pydantic>=2 + - scipp>=24.7.0 + - scippnexus>=23.11.0 + - scipy>=1.7.0 + - scipp[all]>=23.7.0 ; extra == 'all' + - pooch>=1.5 ; extra == 'all' + - hypothesis>=6.100 ; extra == 'test' + - ipympl>0.9.0 ; extra == 'test' + - ipykernel>6.30 ; extra == 'test' + - pace-neutrons>=0.3 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - psutil>=5.0 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - pytest-xdist>=3.0 ; extra == 'test' + - pythreejs>=2.4.1 ; extra == 'test' + - sciline>=25.1.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + name: scippnexus + version: 26.1.1 + sha256: 899a0a5e71291b7809d902c17b6c74addf5a805397eabcec557491ff74eead12 + requires_dist: + - scipp>=24.2.0 + - scipy>=1.10.0 + - h5py>=3.12 + - pytest>=7.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: 37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + name: scipy + version: 1.17.1 + sha256: 7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl + name: scipy + version: 1.17.1 + sha256: a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + sha256: 8fc024bf1a7b99fc833b131ceef4bef8c235ad61ecb95a71a6108be2ccda63e8 + md5: b70e2d44e6aa2beb69ba64206a16e4c6 + depends: + - __osx + - pyobjc-framework-cocoa + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/send2trash?source=hash-mapping + size: 22519 + timestamp: 1770937603551 +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + sha256: 305446a0b018f285351300463653d3d3457687270e20eda37417b12ee386ef76 + md5: 6ac53f3fff2c416d63511843a04646fa + depends: + - __win + - pywin32 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/send2trash?source=hash-mapping + size: 22864 + timestamp: 1770937641143 +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + sha256: 59656f6b2db07229351dfb3a859c35e57cc8e8bcbc86d4e501bff881a6f771f1 + md5: 28eb91468df04f655a57bcfbb35fc5c5 + depends: + - __linux + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/send2trash?source=hash-mapping + size: 24108 + timestamp: 1770937597662 +- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + sha256: 82088a6e4daa33329a30bc26dc19a98c7c1d3f05c0f73ce9845d4eab4924e9e1 + md5: 8e194e7b992f99a5015edbd4ebd38efd + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/setuptools?source=hash-mapping + size: 639697 + timestamp: 1773074868565 +- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + name: shellingham + version: 1.5.4 + sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + name: simple-websocket + version: 1.1.0 + sha256: 4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c + requires_dist: + - wsproto + - tox ; extra == 'dev' + - flake8 ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - sphinx ; extra == 'docs' + requires_python: '>=3.6' +- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d + md5: 3339e3b65d58accf4ca4fb8748ab16b3 + depends: + - python >=3.9 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/six?source=hash-mapping + size: 18455 + timestamp: 1753199211006 +- pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + name: smmap + version: 5.0.3 + sha256: c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad + md5: 03fe290994c5e4ec17293cfb6bdce520 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/sniffio?source=hash-mapping + size: 15698 + timestamp: 1762941572482 +- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + sha256: 23b71ecf089967d2900126920e7f9ff18cdcef82dbff3e2f54ffa360243a17ac + md5: 18de09b20462742fe093ba39185d9bac + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/soupsieve?source=hash-mapping + size: 38187 + timestamp: 1769034509657 +- pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + name: spdx-headers + version: 1.5.1 + sha256: 73bcb1ed087824b55ccaa497d03d8f0f0b0eaf30e5f0f7d5bbd29d2c4fe78fcf + requires_dist: + - chardet>=5.2.0 + - requests>=2.32.3 + - black>=23.0.0 ; extra == 'dev' + - build>=0.10.0 ; extra == 'dev' + - hatch>=1.9.0 ; extra == 'dev' + - isort>=5.12.0 ; extra == 'dev' + - mypy>=1.0.0 ; extra == 'dev' + - pre-commit>=4.3.0 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'dev' + - pytest>=7.0.0 ; extra == 'dev' + - ruff>=0.5.0 ; extra == 'dev' + - twine>=4.0.0 ; extra == 'dev' + - types-requests>=2.31.0.6 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'test' + - pytest-mock>=3.10.0 ; extra == 'test' + - pytest>=7.0.0 ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl + name: spglib + version: 2.6.0 + sha256: ff1632524f6ac0031423474e48d6b69f4932ecb7eb4446a501f59619e2b5cbc9 + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl + name: spglib + version: 2.6.0 + sha256: 12db7a0d6ad84c55e61eda67590a438edeb48e57ffd5df868cd931b57fb8c630 + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: spglib + version: 2.6.0 + sha256: cc9d856d7cc936dc73b6b303aaf8b2fb4230a8527659373450c6e1139cbb2a5c + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl + name: sqlalchemy + version: 2.0.49 + sha256: 12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl + name: sqlalchemy + version: 2.0.49 + sha256: df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/cd/f5/038741f5e747a5f6ea3e72487211579d8cbea5eb9827a9cbd61d0108c4bd/sqlalchemy-2.0.49-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: sqlalchemy + version: 2.0.49 + sha256: 47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 + md5: b1b505328da7a6b246787df4b5a49fbc + depends: + - asttokens + - executing + - pure_eval + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/stack-data?source=hash-mapping + size: 26988 + timestamp: 1733569565672 +- pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + name: svglib + version: 1.5.1 + sha256: 3ae765d3a9409ee60c0fb4d24c2deb6a80617aa927054f5bcd7fc98f0695e587 + requires_dist: + - reportlab + - lxml + - tinycss2>=0.6.0 + - cssselect2>=0.2.0 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + name: svglib + version: 1.6.0 + sha256: 9aea8e2e81cbbf9c844460e4c7dc90e0a06aea7983bc201975ccd279d7b2d194 + requires_dist: + - cssselect2>=0.2.0 + - lxml>=6.0.0 + - reportlab>=4.4.3 + - rlpycairo>=0.4.0 + - tinycss2>=0.6.0 + - mypy>=1.18.1 ; extra == 'dev' + - pre-commit>=4.3.0 ; extra == 'dev' + - pytest-cov>=7.0.0 ; extra == 'dev' + - pytest-runner>=6.0.1 ; extra == 'dev' + - pytest>=8.3.5 ; extra == 'dev' + - ruff>=0.13.0 ; extra == 'dev' + - tox>=4.30.2 ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + name: sympy + version: 1.14.0 + sha256: e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5 + requires_dist: + - mpmath>=1.1.0,<1.4 + - pytest>=7.1.0 ; extra == 'dev' + - hypothesis>=6.70.0 ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + name: tabulate + version: 0.10.0 + sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 + requires_dist: + - wcwidth ; extra == 'widechars' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + sha256: b375e8df0d5710717c31e7c8e93c025c37fa3504aea325c7a55509f64e5d4340 + md5: e43ca10d61e55d0a8ec5d8c62474ec9e + depends: + - __win + - pywinpty >=1.1.0 + - python >=3.10 + - tornado >=6.1.0 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/terminado?source=hash-mapping + size: 23665 + timestamp: 1766513806974 +- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + sha256: 6b6727a13d1ca6a23de5e6686500d0669081a117736a87c8abf444d60c1e40eb + md5: 17b43cee5cc84969529d5d0b0309b2cb + depends: + - __unix + - ptyprocess + - python >=3.10 + - tornado >=6.1.0 + - python + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/terminado?source=hash-mapping + size: 24749 + timestamp: 1766513766867 +- conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + sha256: cad582d6f978276522f84bd209a5ddac824742fe2d452af6acf900f8650a73a2 + md5: f1acf5fdefa8300de697982bcb1761c9 + depends: + - python >=3.5 + - webencodings >=0.4 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/tinycss2?source=hash-mapping + size: 28285 + timestamp: 1729802975370 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + constrains: + - xorg-libx11 >=1.8.12,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 + md5: 0481bfd9814bf525bd4b3ee4b51494c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: TCL + license_family: BSD + purls: [] + size: 3526350 + timestamp: 1769460339384 +- pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + name: tof + version: 26.3.0 + sha256: e89783a072b05fdb53d9e76fbf919dc8935e75e118fdaf17ca5cc33727ef002b + requires_dist: + - plopp>=23.10.0 + - pooch>=1.5.0 + - scipp>=25.1.0 + - lazy-loader>=0.3 + - pytest>=8.0 ; extra == 'test' + - scippneutron>=24.12.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + name: tokenize-rt + version: 6.2.0 + sha256: a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44 + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + sha256: 91cafdb64268e43e0e10d30bd1bef5af392e69f00edd34dfaf909f69ab2da6bd + md5: b5325cf06a000c5b14970462ff5e4d58 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/tomli?source=hash-mapping + size: 21561 + timestamp: 1774492402955 +- pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl + name: toolz + version: 1.1.0 + sha256: 15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda + sha256: cd8bc08ca661291cfbb05581b79f7e6a6971a072a54a335abcea5460c1230880 + md5: 73b44a114241e564deb5846e7394bf19 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=compressed-mapping + size: 876817 + timestamp: 1774358035290 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + sha256: 9e8497e1ecca77d03c6be2d3b5f901dfe0ab99686af4fb94ab418b7d449ac547 + md5: 6c0b0ae017b5bfd9c8d718217efd8f14 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 882996 + timestamp: 1774358035145 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda + sha256: 572923958ec987f3f68e228dfec243c89ab94b50398731215d36e2e040db8703 + md5: 6f12d9ff025ab1875dff67ad779ca29d + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 875022 + timestamp: 1774358570256 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda + sha256: c5b0ee042d8a0b88a3823226dc95b794c042c498aee330aa9b4d78bfad01d099 + md5: 303333dd882dfeb303cc8bfac178464b + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 883472 + timestamp: 1774358832451 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda + sha256: 71f58fe09f7729ad82c8eb942e775ddeffcef454483911d19d1041ac5d81eec3 + md5: b004afcc680af88cb877978e71d42667 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 878544 + timestamp: 1774358187588 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + sha256: b97fab804ab457cf4157103289317e3619e801a77410e756bb35c6223418cc6e + md5: 7d53f0d25ad5fd7d6962ce4eb385fb07 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 883689 + timestamp: 1774358224157 +- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + sha256: dfb681579be59c2e790c95f7f49b7529a9b0511d6385ad276e3c8988cbd54d2c + md5: 4bada6a6d908a27262af8ebddf4f7492 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/traitlets?source=compressed-mapping + size: 115165 + timestamp: 1778074251714 +- pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + name: traittypes + version: 0.2.3 + sha256: 49016082ce740d6556d9bb4672ee2d899cd14f9365f17cbb79d5d96b47096d4e + requires_dist: + - traitlets>=4.2.2 + - numpy ; extra == 'test' + - pandas ; extra == 'test' + - xarray ; extra == 'test' + - pytest ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + name: trove-classifiers + version: 2026.4.28.13 + sha256: 8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 +- pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + name: typeguard + version: 4.5.1 + sha256: 44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 + requires_dist: + - importlib-metadata>=3.6 ; python_full_version < '3.10' + - typing-extensions>=4.14.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + name: typer + version: 0.25.1 + sha256: 75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 + requires_dist: + - click>=8.2.1 + - shellingham>=1.3.0 + - rich>=13.8.0 + - annotated-doc>=0.0.2 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c + md5: edd329d7d3a4ab45dcf905899a7a6115 + depends: + - typing_extensions ==4.15.0 pyhcf101f3_0 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 91383 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a + md5: 53f5409c5cfd6c5a66417d68e3f0a864 + depends: + - python >=3.10 + - typing_extensions >=4.12.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/typing-inspection?source=compressed-mapping + size: 20935 + timestamp: 1777105465795 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 + md5: 0caa1af407ecff61170c9437a808404d + depends: + - python >=3.10 + - python + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/typing-extensions?source=hash-mapping + size: 51692 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c + md5: f6d7aa696c67756a650e91e15e88223c + depends: + - python >=3.9 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/typing-utils?source=hash-mapping + size: 15183 + timestamp: 1733331395943 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain + purls: [] + size: 119135 + timestamp: 1767016325805 +- pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + name: tzlocal + version: 5.3.1 + sha256: eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d + requires_dist: + - tzdata ; sys_platform == 'win32' + - pytest>=4.3 ; extra == 'devenv' + - pytest-mock>=3.3 ; extra == 'devenv' + - pytest-cov ; extra == 'devenv' + - check-manifest ; extra == 'devenv' + - zest-releaser ; extra == 'devenv' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + purls: [] + size: 694692 + timestamp: 1756385147981 +- pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + name: uncertainties + version: 3.2.3 + sha256: 313353900d8f88b283c9bad81e7d2b2d3d4bcc330cbace35403faaed7e78890a + requires_dist: + - numpy ; extra == 'arrays' + - pytest ; extra == 'test' + - pytest-codspeed ; extra == 'test' + - pytest-cov ; extra == 'test' + - scipy ; extra == 'test' + - sphinx ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - python-docs-theme ; extra == 'doc' + - uncertainties[arrays,doc,test] ; extra == 'all' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 + md5: e7cb0f5745e4c5035a460248334af7eb + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/uri-template?source=hash-mapping + size: 23990 + timestamp: 1733323714454 +- pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + name: uritools + version: 6.1.0 + sha256: f1b699052459711f1dd03721ca79341dc345054e6286f47313f8bce777782415 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a + md5: 9272daa869e03efe68833e3dc7a02130 + depends: + - backports.zstd >=1.0.0 + - brotli-python >=1.2.0 + - h2 >=4,<5 + - pysocks >=1.5.6,<2.0,!=1.5.7 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/urllib3?source=hash-mapping + size: 103172 + timestamp: 1767817860341 +- pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + name: validate-pyproject + version: '0.25' + sha256: f9d05e2686beff82f9ea954f582306b036ced3d3feb258c1110f2c2a495b1981 + requires_dist: + - fastjsonschema>=2.16.2,<=3 + - packaging>=24.2 ; extra == 'all' + - trove-classifiers>=2021.10.20 ; extra == 'all' + - tomli>=1.2.1 ; python_full_version < '3.11' and extra == 'all' + - validate-pyproject-schema-store ; extra == 'store' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + name: varname + version: 1.0.0 + sha256: 1125bfe981c3bbbe56988f5cb85fdcd7cad923b153283c2d464aea8b4c833d51 + requires_dist: + - executing>=2.1 + - typing-extensions>=4.13 ; python_full_version < '3.10' + - asttokens==3.* ; extra == 'all' + - pure-eval==0.* ; extra == 'all' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f + depends: + - vc14_runtime >=14.44.35208 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_34 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 115235 + timestamp: 1767320173250 +- pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + name: versioningit + version: 3.3.0 + sha256: 23b1db3c4756cded9bd6b0ddec6643c261e3d0c471707da3e0b230b81ce53e4b + requires_dist: + - importlib-metadata>=3.6 ; python_full_version < '3.10' + - packaging>=17.1 + - tomli>=1.2,<3.0 ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + name: verspec + version: 0.1.0 + sha256: 741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 + requires_dist: + - coverage ; extra == 'test' + - flake8>=3.7 ; extra == 'test' + - mypy ; extra == 'test' + - pretend ; extra == 'test' + - pytest ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + name: virtualenv + version: 21.3.1 + sha256: d1a71cf58f2f9228fff23a1f6ec15d39785c6b32e03658d104974247145edd35 + requires_dist: + - distlib>=0.3.7,<1 + - filelock>=3.24.2,<4 ; python_full_version >= '3.10' + - filelock>=3.16.1,<=3.19.1 ; python_full_version < '3.10' + - importlib-metadata>=6.6 ; python_full_version < '3.8' + - platformdirs>=3.9.1,<5 + - python-discovery>=1.2.2 + - typing-extensions>=4.13.2 ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + name: watchdog + version: 6.0.0 + sha256: 20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + name: watchdog + version: 6.0.0 + sha256: cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + sha256: 1ee2d8384972ecbf8630ce8a3ea9d16858358ad3e8566675295e66996d5352da + md5: eb9538b8e55069434a18547f43b96059 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/wcwidth?source=compressed-mapping + size: 82917 + timestamp: 1777744489106 +- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 + md5: 6639b6b0d8b5a284f027a2003669aa65 + depends: + - python >=3.10 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/webcolors?source=hash-mapping + size: 18987 + timestamp: 1761899393153 +- conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 + md5: 2841eb5bfc75ce15e9a0054b98dcd64d + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/webencodings?source=hash-mapping + size: 15496 + timestamp: 1733236131358 +- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 + md5: 2f1ed718fcd829c184a6d4f0f2e07409 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/websocket-client?source=hash-mapping + size: 61391 + timestamp: 1759928175142 +- pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + name: widgetsnbextension + version: 4.0.15 + sha256: 8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 + requires_python: '>=3.7' +- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f + md5: 46e441ba871f524e2b067929da3051c2 + depends: + - __win + - python >=3.9 + license: LicenseRef-Public-Domain + purls: + - pkg:pypi/win-inet-pton?source=hash-mapping + size: 9555 + timestamp: 1733130678956 +- conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + sha256: 9df10c5b607dd30e05ba08cbd940009305c75db242476f4e845ea06008b0a283 + md5: 1cee351bf20b830d991dbe0bc8cd7dfe + license: MIT + license_family: MIT + purls: [] + size: 1176306 +- pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + name: wsproto + version: 1.3.2 + sha256: 61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584 + requires_dist: + - h11>=0.16.0,<1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + name: xhtml2pdf + version: 0.2.17 + sha256: 61a7ecac829fed518f7dbcb916e9d56bea6e521e02e54644b3d0ca33f0658315 + requires_dist: + - arabic-reshaper>=3.0.0 + - html5lib>=1.1 + - pillow>=8.1.1 + - pyhanko>=0.12.1 + - pyhanko-certvalidator>=0.19.5 + - pypdf>=3.1.0 + - python-bidi>=0.5.0 + - reportlab>=4.0.4,<5 + - svglib>=1.2.1 + - reportlab[pycairo]>=4.0.4,<5 ; extra == 'pycairo' + - reportlab[renderpm]>=4.0.4,<5 ; extra == 'renderpm' + - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'test' + - tox ; extra == 'test' + - coverage>=5.3 ; extra == 'test' + - sphinx>=6 ; extra == 'docs' + - sphinx-rtd-theme>=0.5.0 ; extra == 'docs' + - sphinx-reredirects>=0.1.3 ; extra == 'docs' + - build ; extra == 'release' + - twine ; extra == 'release' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + name: xraydb + version: 4.5.8 + sha256: 2215baafa6a03d00d0254a94525aafc6493c8c285e4ac4477fbd6271b25e6a51 + requires_dist: + - numpy>=1.19 + - scipy>=1.6 + - sqlalchemy>=2.0.1 + - platformdirs + - build ; extra == 'dev' + - twine ; extra == 'dev' + - sphinx ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - xraydb[dev,doc,test] ; extra == 'all' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad + md5: a77f85f77be52ff59391544bfe73390a + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + purls: [] + size: 85189 + timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac + md5: 78a0fe9e9c50d2c381e8ee47e3ea437d + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 83386 + timestamp: 1753484079473 +- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 + md5: 433699cba6602098ae8957a323da2664 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 63944 + timestamp: 1753484092156 +- pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: yarl + version: 1.23.0 + sha256: 34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: yarl + version: 1.23.0 + sha256: 99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + name: yarl + version: 1.23.0 + sha256: 7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl + name: yarl + version: 1.23.0 + sha256: dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + sha256: 325d370b28e2b9cc1f765c5b4cdb394c91a5d958fbd15da1a14607a28fee09f6 + md5: 755b096086851e1193f3b10347415d7c + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - krb5 >=1.22.2,<1.23.0a0 + - libsodium >=1.0.21,<1.0.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 311150 + timestamp: 1772476812121 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + sha256: 2705360c72d4db8de34291493379ffd13b09fd594d0af20c9eefa8a3f060d868 + md5: e85dcd3bde2b10081cdcaeae15797506 + depends: + - __osx >=11.0 + - libcxx >=19 + - krb5 >=1.22.2,<1.23.0a0 + - libsodium >=1.0.21,<1.0.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 245246 + timestamp: 1772476886668 +- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + sha256: b8568dfde46edf3455458912ea6ffb760e4456db8230a0cf34ecbc557d3c275f + md5: 1ab0237036bfb14e923d6107473b0021 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libsodium >=1.0.21,<1.0.22.0a0 + - krb5 >=1.22.2,<1.23.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 265665 + timestamp: 1772476832995 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + sha256: 523616c0530d305d2216c2b4a8dfd3872628b60083255b89c5e0d8c42e738cca + md5: e1c36c6121a7c9c76f2f148f1e83b983 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/zipp?source=compressed-mapping + size: 24461 + timestamp: 1776131454755 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 388453 + timestamp: 1764777142545 diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 00000000..b0fb2b8d --- /dev/null +++ b/pixi.toml @@ -0,0 +1,278 @@ +########### +# WORKSPACE +########### + +[workspace] + +# Supported platforms for the lock file (pixi.lock) +platforms = ['win-64', 'linux-64', 'osx-arm64'] + +# Channels for fetching packages +channels = ['nodefaults', 'conda-forge'] + +########## +# FEATURES +########## + +# Default features: + +[activation.env] +PYTHONIOENCODING = 'utf-8' + +[system-requirements] +# Set minimum supported version for macOS to be 14.0 to ensure packages +# like `scipp` that only have wheels for macOS 14.0+ (macosx_14_0_arm64) +# are used instead of building from source. This is a workaround for +# Pixi, see https://github.com/prefix-dev/pixi/issues/5667 +macos = '14.0' + +# Non-default features: + +# Set specific Python versions to be used in CI testing. + +[feature.py-min.dependencies] +python = '3.11.*' + +[feature.py-max.dependencies] +python = '3.13.*' + +# Development dependencies for local development and testing with +# editable installations. + +[feature.dev.dependencies] +nodejs = '*' # Required for Prettier (non-Python formatting) +jupyterlab = '*' # Jupyter notebooks +ipython = '*' # Interactive Python shell +pixi-kernel = '*' # Pixi Jupyter kernel + +[feature.dev.pypi-dependencies] +pip = '*' +easyreflectometry = { path = '.', editable = true, extras = ['dev'] } + +# User-like behavior for testing with pip-installed dependencies instead +# of editable installations. + +[feature.user.dependencies] +jupyterlab = '*' # Jupyter notebooks +ipython = '*' # Interactive Python shell +pixi-kernel = '*' # Pixi Jupyter kernel + +[feature.user.pypi-dependencies] +pip = '*' +easydiffraction = '*' + +############## +# ENVIRONMENTS +############## + +[environments] + +# The `default` feature is always included in all environments. +# Additional features can be specified per environment. + +# Specific environments for CI testing with different Python versions. +py-311-env = { features = ['py-min', 'dev'] } +py-313-env = { features = ['py-max', 'dev'] } + +# The `default` environment is developer-oriented for local development +# and testing with editable installation of the current package. +default = { features = ['py-max', 'dev'] } + +# The `user` environment allows testing with pip-installed dependencies +# instead of editable installation of the current package. +user = { features = ['py-max', 'user'] } + +####### +# TASKS +####### + +[tasks] + +################## +# 🧪 Testing Tasks +################## + +unit-tests = 'python -m pytest tests/unit/ --color=yes -v' +functional-tests = 'python -m pytest tests/functional/ --color=yes -v' +integration-tests = 'python -m pytest tests/integration/ --color=yes -n auto -v' +notebook-tests = 'python -m pytest --nbmake docs/docs/tutorials/**/ --nbmake-timeout=1200 --color=yes -n auto -v' + +test = { depends-on = ['unit-tests'] } + +########### +# ✔️ Checks +########### + +pyproject-check = 'python -m validate_pyproject pyproject.toml' +docstring-lint-check = 'pydoclint --quiet src/' +notebook-lint-check = 'nbqa ruff docs/docs/tutorials/' +py-lint-check = 'ruff check src/ tests/ docs/docs/tutorials/' +py-format-check = 'ruff format --check src/ tests/ docs/docs/tutorials/' +nonpy-format-check = 'npx prettier --list-different --config=prettierrc.toml --ignore-unknown .' +nonpy-format-check-modified = 'python tools/nonpy_prettier_modified.py' + +check = 'pre-commit run --hook-stage manual --all-files' + +########## +# 🛠️ Fixes +########## + +docstring-transform = 'pixi run docstripy src/ -s=numpy -w' +docstring-format-fix = 'format-docstring src/' +notebook-lint-fix = 'nbqa ruff --fix docs/docs/tutorials/' +py-lint-fix = 'ruff check --fix src/ tests/ docs/docs/tutorials/' +py-lint-fix-unsafe = 'ruff check --fix --unsafe-fixes src/ tests/ docs/docs/tutorials/' +py-format-fix = 'ruff format src/ tests/ docs/docs/tutorials/' +nonpy-format-fix = 'npx prettier --write --list-different --config=prettierrc.toml --ignore-unknown .' +nonpy-format-fix-modified = 'python tools/nonpy_prettier_modified.py --write' +success-message = 'echo "✅ All auto-formatting steps completed successfully!"' + +fix = { depends-on = [ + 'docstring-format-fix', + 'py-format-fix', + 'py-lint-fix', + 'nonpy-format-fix', + 'notebook-lint-fix', + 'success-message', +] } + +#################### +# 🧮 Code Complexity +#################### + +complexity-check = 'radon cc -s src/' +complexity-check-json = 'radon cc -s -j src/' +maintainability-check = 'radon mi src/' +maintainability-check-json = 'radon mi -j src/' +raw-metrics = 'radon raw -s src/' +raw-metrics-json = 'radon raw -s -j src/' + +############# +# 📊 Coverage +############# + +unit-tests-coverage = 'pixi run unit-tests --cov=src/easyreflectometry --cov-report=term-missing' +functional-tests-coverage = 'pixi run functional-tests --cov=src/easyreflectometry --cov-report=term-missing' +integration-tests-coverage = 'pixi run integration-tests --cov=src/easyreflectometry --cov-report=term-missing' +docstring-coverage = 'interrogate -c pyproject.toml src/easyreflectometry' + +cov = { depends-on = [ + 'docstring-coverage', + 'unit-tests-coverage', + 'integration-tests-coverage', +] } + +######################## +# 📓 Notebook Management +######################## + +notebook-convert = 'jupytext docs/docs/tutorials/*.py --from py:percent --to ipynb' +notebook-strip = 'nbstripout docs/docs/tutorials/**/*.ipynb' +notebook-tweak = 'python tools/tweak_notebooks.py docs/docs/tutorials/**/*.ipynb' +notebook-exec = 'python -m pytest --nbmake docs/docs/tutorials/ --nbmake-timeout=1200 --overwrite --color=yes -n auto -v' + +notebook-prepare = { depends-on = [ + #'notebook-convert', + 'notebook-strip', + #'notebook-tweak', +] } + +######################## +# 📚 Documentation Tasks +######################## + +docs-vars = "JUPYTER_PLATFORM_DIRS=1 PYTHONWARNINGS='ignore::RuntimeWarning'" +docs-pre = 'pixi run docs-vars python -m mkdocs' +docs-serve = 'pixi run docs-pre serve -f docs/mkdocs.yml' +docs-serve-dirty = 'pixi run docs-serve --dirty' +docs-build = 'pixi run docs-pre build -f docs/mkdocs.yml' +docs-build-local = 'pixi run docs-build --no-directory-urls' + +docs-deploy-pre = 'mike deploy -F docs/mkdocs.yml --push --branch gh-pages --update-aliases --alias-type redirect' +docs-set-default-pre = 'mike set-default -F docs/mkdocs.yml --push --branch gh-pages' + +docs-update-assets = 'python tools/update_docs_assets.py' + +############################## +# 📦 Template Management Tasks +############################## + +copier-copy = 'copier copy gh:easyscience/templates . --data-file .copier-answers.yml --data template_type=lib' +copier-recopy = 'copier recopy --data-file .copier-answers.yml --data template_type=lib' +copier-update = 'copier update --data-file .copier-answers.yml --data template_type=lib' + +##################### +# 🪝 Pre-commit Hooks +##################### + +pre-commit-clean = 'pre-commit clean' +pre-commit-install = 'pre-commit install --hook-type pre-commit --hook-type pre-push --overwrite' +pre-commit-uninstall = 'pre-commit uninstall --hook-type pre-commit --hook-type pre-push' +pre-commit-setup = { depends-on = [ + 'pre-commit-clean', + 'pre-commit-uninstall', + 'pre-commit-install', +] } + +################# +# 🐙️ GitHub Tasks +################# + +repo-wiki = 'gh api -X PATCH repos/easyscience/reflectometry-lib -f has_wiki=false' +repo-discussions = 'gh api -X PATCH repos/easyscience/reflectometry-lib -f has_discussions=true' +repo-description = "gh api -X PATCH repos/easyscience/reflectometry-lib -f description='Reflectometry data analysis'" +repo-homepage = "gh api -X PATCH repos/easyscience/reflectometry-lib -f homepage='https://easyscience.github.io/reflectometry-lib'" +repo-config = { depends-on = [ + 'repo-wiki', + 'repo-discussions', + 'repo-description', + 'repo-homepage', +] } + +master-protection = 'gh api -X POST repos/easyscience/reflectometry-lib/rulesets --input .github/configs/rulesets-master.json' +develop-protection = 'gh api -X POST repos/easyscience/reflectometry-lib/rulesets --input .github/configs/rulesets-develop.json' +gh-pages-protection = 'gh api -X POST repos/easyscience/reflectometry-lib/rulesets --input .github/configs/rulesets-gh-pages.json' +branch-protection = { depends-on = [ + 'master-protection', + 'develop-protection', + 'gh-pages-protection', +] } + +pages-deployment = 'gh api -X POST repos/easyscience/reflectometry-lib/pages --input .github/configs/pages-deployment.json' + +github-labels = 'python tools/update_github_labels.py' + +######################### +# ⚖️ SPDX License Headers +######################### + +license-remove = 'python tools/license_headers.py remove src/ tests/ --exclude-from-pyproject-toml tool.ruff.exclude' +license-add = 'python tools/license_headers.py add src/ tests/ --exclude-from-pyproject-toml tool.ruff.exclude' +license-check = 'python tools/license_headers.py check src/ tests/ --exclude-from-pyproject-toml tool.ruff.exclude' + +#################################### +# 🚀 Other Development & Build Tasks +#################################### + +default-build = 'python -m build' +dist-build = 'python -m build --wheel --outdir dist' + +npm-config = 'npm config set registry https://registry.npmjs.org/' +prettier-install = 'npm install --no-save --no-audit --no-fund prettier prettier-plugin-toml' + +clean-pycache = "find . -type d -name '__pycache__' -prune -exec rm -rf '{}' +" + +post-install = { depends-on = [ + 'npm-config', + 'prettier-install', + #'pre-commit-setup', +] } + +########################## +# 🔗 Main Package Shortcut +########################## +easyreflectometry = 'python -m easyreflectometry' + +[dependencies] +ruff = ">=0.15.12,<0.16" +copier = ">=9.15.0,<10" diff --git a/prettierrc.toml b/prettierrc.toml new file mode 100644 index 00000000..b98c86eb --- /dev/null +++ b/prettierrc.toml @@ -0,0 +1,22 @@ +plugins = [ + "prettier-plugin-toml", # use the TOML plugin +] + +endOfLine = 'lf' # change line endings to LF +proseWrap = 'always' # change wrapping in Markdown files +semi = false # remove semicolons +singleQuote = true # use single quotes instead of double quotes +tabWidth = 2 # change tab width to 2 spaces +useTabs = false # use spaces instead of tabs + +printWidth = 79 # wrap lines at 79 characters + +[[overrides]] +files = ["*.md"] +[overrides.options] +printWidth = 72 # wrap Markdown files at 72 characters + +[[overrides]] +files = ["*.yml", "*.yaml"] +[overrides.options] +printWidth = 88 # wrap YAML files at 88 characters diff --git a/pyproject.toml b/pyproject.toml index ec3df724..681c5562 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,164 +1,345 @@ -[build-system] -requires = [ - "hatchling<=1.21.0", - "setuptools-git-versioning", -] -build-backend = "hatchling.build" - -[tool.setuptools-git-versioning] -enabled = true +############################### +# Configuration for the project +############################### [project] -name = "easyreflectometry" -dynamic = ["version"] -description = "A reflectometry python package built on the EasyScience framework." -readme = "README.md" -authors = [{name = "EasyScience contributors"}] -license = { file = "LICENSE" } +name = 'easyreflectometry' +dynamic = ['version'] # Use versioningit to manage the version +description = 'Reflectometry data analysis' +authors = [{ name = 'EasyScience contributors' }] +readme = 'README.md' +license = 'BSD-3-Clause' +license-files = ['LICENSE'] classifiers = [ - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Topic :: Scientific/Engineering", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Development Status :: 3 - Alpha" + 'Intended Audience :: Science/Research', + 'Topic :: Scientific/Engineering', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ] - -requires-python = ">=3.11,<3.14" - +requires-python = '>=3.11' dependencies = [ - "easyscience", - "scipp", - "refnx", - "refl1d>=1.0.0", - "orsopy", - "svglib<1.6 ; platform_system=='Linux' or sys_platform == 'darwin'", - "xhtml2pdf", - "bumps", + 'easyscience', + 'scipp', + 'refnx', + 'refl1d>=1.0.0', + 'orsopy', + 'svglib<1.6 ; platform_system=="Linux" or sys_platform == "darwin"', + 'xhtml2pdf', + 'bumps', + 'pooch', ] [project.optional-dependencies] dev = [ - "build", - "codecov", - "coverage", - "coveralls", - "flake8", - "ipykernel", - "jupyter", - "jupyterlab", - "plopp", - "pooch", - "pytest", - "pytest-cov", - "ruff", - "toml", - "yapf", -] - -docs = [ - "myst_parser", - "nbsphinx", - "plopp", - "sphinx<=8.1.3", - "sphinx_autodoc_typehints", - "sphinx_book_theme", - "sphinx-copybutton", - "toml" + 'GitPython', # Interact with Git repositories + 'build', # Building the package + 'pre-commit', # Pre-commit hooks + 'jinja2', # Templating + 'nbmake', # Building notebooks + 'nbstripout', # Strip output from notebooks + 'nbqa', # Linting and formatting notebooks + 'pytest', # Testing + 'pytest-cov', # Test coverage + 'pytest-xdist', # Enable parallel testing + 'ruff', # Linting and formatting code + 'radon', # Code complexity and maintainability + 'validate-pyproject[all]', # Validate pyproject.toml + 'versioningit', # Automatic versioning from git tags + 'jupytext', # Jupyter notebook text format support + 'jupyterquiz', # Quizzes in Jupyter notebooks + 'plopp', # Plotting in Jupyter notebooks + 'pydoclint', # Docstring linter + 'format-docstring', # Docstring formatter + 'docstripy', # Convert docstrings to other formats + 'interrogate', # Docstring coverage checker + 'copier', # Template management + 'mike', # MkDocs: Versioned documentation support + 'mkdocs', # Static site generator + 'mkdocs-material', # Documentation framework on top of MkDocs + 'mkdocs-autorefs', # MkDocs: Auto-references support + 'mkdocs-jupyter', # MkDocs: Jupyter notebook support + 'mkdocs-plugin-inline-svg', # MkDocs: Inline SVG support + 'mkdocs-markdownextradata-plugin', # MkDocs: Markdown extra data support, such as global variables + 'mkdocstrings-python', # MkDocs: Python docstring support + 'pyyaml', # YAML parser + 'spdx-headers', # SPDX license header validation ] [project.urls] -homepage = "https://docs.easyreflectometry.org" -documentation = "https://docs.easyreflectometry.org" +Documentation = 'https://easyscience.github.io/reflectometry-lib' +'Release Notes' = 'https://github.com/easyscience/reflectometry-lib/releases' +'Source Code' = 'https://github.com/easyscience/reflectometry-lib' +'Issue Tracker' = 'https://github.com/easyscience/reflectometry-lib/issues' -[tool.hatch.version] -path = "src/easyreflectometry/__version__.py" +############################ +# Build system configuration +############################ + +[build-system] +build-backend = 'hatchling.build' +requires = ['hatchling', 'versioningit'] + +############################# +# Configuration for hatchling +############################# + +# 'hatch' -- Build system for Python +# https://hatch.pypa.io/ + +[tool.hatch.build.targets.wheel] +packages = ['src/easyreflectometry'] [tool.hatch.metadata] allow-direct-references = true -[tool.hatch.build.targets.sdist] -packages = ["src"] +[tool.hatch.version] +source = 'versioningit' # Use versioningit to manage the version -[tool.hatch.build.targets.wheel] -packages = ["src/easyreflectometry"] +################################ +# Configuration for versioningit +################################ + +# 'versioningit' -- Versioning from git tags +# https://versioningit.readthedocs.io/ + +# Versioningit generates versions from git tags, so we don't need to +# either specify them statically in pyproject.toml or save them in the +# source code. Do not use {distance} in the version format, as it +# forces a version bump for every commit, which triggers unnecessary +# pixi.lock update without any changes to the source code. + +[tool.versioningit.format] +distance = '{base_version}+dev{distance}' # example: 1.2.3.post4+dev3 +dirty = '{base_version}+dirty{distance}' # example: 0.5.8+dirty3 +distance-dirty = '{base_version}+devdirty{distance}' # example: 0.5.8+devdirty3 + +# Configure how versioningit detects versions from Git +# - 'match' ensures it only considers tags starting with 'v' +# - 'default-tag' is used as a fallback when no matching tag is found +[tool.versioningit.vcs] +method = 'git' +match = ['v*'] +default-tag = 'v999.0.0' + +################################ +# Configuration for interrogate +################################ + +# 'interrogate' -- Docstring coverage checker +# https://interrogate.readthedocs.io/en/latest/ + +[tool.interrogate] +fail-under = 0 # Minimum docstring coverage percentage to pass +verbose = 1 +#exclude = ['src/**/__init__.py'] + +####################################### +# Configuration for coverage/pytest-cov +####################################### + +# 'coverage' -- Code coverage measurement tool +# https://coverage.readthedocs.io/en/latest/ [tool.coverage.run] -source = ["src/easyreflectometry"] +branch = true # Measure branch coverage as well +source = ['src'] # Limit coverage to the source code directory + +[tool.coverage.report] +show_missing = true # Show missing lines +skip_covered = false # Skip files with 100% coverage in the report +fail_under = 0 # Minimum coverage percentage to pass + +########################## +# Configuration for pytest +########################## -[tool.github.info] -organization = 'easyScience' -repo = "easyreflectometry" +# 'pytest' -- Testing framework +# https://docs.pytest.org/en/stable/ + +[tool.pytest.ini_options] +addopts = '--import-mode=importlib' +markers = ['fast: mark test as fast (should be run on every push)'] +testpaths = ['tests'] + +######################## +# Configuration for ruff +######################## + +# 'ruff' -- Python linter and code formatter +# https://docs.astral.sh/ruff/rules/ [tool.ruff] -line-length = 127 -exclude = [ - "docs", -] +exclude = ['tmp'] +indent-width = 4 +# line-length = 99 # See also `max-line-length` in [tool.ruff.lint.pycodestyle] +line-length = 128 # See also `max-line-length` in [tool.ruff.lint.pycodestyle] +preview = true # Enable new rules that are not yet stable, like DOC + +# Formatting options for Ruff [tool.ruff.format] -quote-style = "single" +docstring-code-format = true # Whether to format code snippets in docstrings +docstring-code-line-length = 99 # Line length for code snippets in docstrings +# docstring-code-line-length = 72 # Line length for code snippets in docstrings +indent-style = 'space' # PEP 8 recommends using spaces over tabs +quote-style = 'single' # But double quotes in docstrings (PEP 8, PEP 257) -[tool.ruff.lint.per-file-ignores] -# allow asserts in test files -"*test_*.py" = ["S101"] +# Linting rules to use with Ruff [tool.ruff.lint] select = [ - # flake8 settings from existing CI setup - "E9", "F63", "F7", "F82", - # Code should be polished to fulfill all cases below - # https://docs.astral.sh/ruff/rules/ - # pycodestyle - "E", - # Pyflakes - "F", - # pyupgrade -# "UP", - # flake8-bugbear -# "B", - # flake8-simplify -# "SIM", - # isort - "I", - # flake8-bandit - "S", + # Various rules + #'C90', # https://docs.astral.sh/ruff/rules/#mccabe-c90 + #'D', # https://docs.astral.sh/ruff/rules/#pydocstyle-d + 'F', # https://docs.astral.sh/ruff/rules/#pyflakes-f + #'FLY', # https://docs.astral.sh/ruff/rules/#flynt-fly + #'FURB', # https://docs.astral.sh/ruff/rules/#refurb-furb + 'I', # https://docs.astral.sh/ruff/rules/#isort-i + #'N', # https://docs.astral.sh/ruff/rules/#pep8-naming-n + #'NPY', # https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy + #'PGH', # https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh + #'PERF', # https://docs.astral.sh/ruff/rules/#perflint-perf + #'RUF', # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf + #'TRY', # https://docs.astral.sh/ruff/rules/#tryceratops-try + #'UP', # https://docs.astral.sh/ruff/rules/#pyupgrade-up + # pycodestyle (E, W) rules + 'E', # https://docs.astral.sh/ruff/rules/#error-e + 'W', # https://docs.astral.sh/ruff/rules/#warning-w + # Pylint (PL) rules + #'PLC', # https://docs.astral.sh/ruff/rules/#convention-plc + #'PLE', # https://docs.astral.sh/ruff/rules/#error-ple + #'PLR', # https://docs.astral.sh/ruff/rules/#refactor-plr + #'PLW', # https://docs.astral.sh/ruff/rules/#warning-plw + # flake8 rules + #'A', # https://docs.astral.sh/ruff/rules/#flake8-builtins-a + #'ANN', # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann + #'ARG', # https://docs.astral.sh/ruff/rules/#flake8-unused-arguments-arg + #'ASYNC', # https://docs.astral.sh/ruff/rules/#flake8-async-async + #'B', # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + #'BLE', # https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble + #'C4', # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + #'COM', # https://docs.astral.sh/ruff/rules/#flake8-commas-com + #'DTZ', # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz + #'EM', # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em + #'FA', # https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa + #'FBT', # https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt + #'FIX', # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix + #'G', # https://docs.astral.sh/ruff/rules/#flake8-logging-format-g + #'ICN', # https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn + #'INP', # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp + #'ISC', # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc + #'LOG', # https://docs.astral.sh/ruff/rules/#flake8-logging-log + #'PIE', # https://docs.astral.sh/ruff/rules/#flake8-pie-pie + #'PT', # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt + #'PTH', # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth + #'PYI', # https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi + #'RET', # https://docs.astral.sh/ruff/rules/#flake8-return-ret + #'RSE', # https://docs.astral.sh/ruff/rules/#flake8-raise-rse + 'S', # https://docs.astral.sh/ruff/rules/#flake8-bandit-s + #'SIM', # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim + #'SLF', # https://docs.astral.sh/ruff/rules/#flake8-self-slf + #'SLOT', # https://docs.astral.sh/ruff/rules/#flake8-slots-slot + #'T20', # https://docs.astral.sh/ruff/rules/#flake8-print-t20 + #'TC', # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tc + #'TD', # https://docs.astral.sh/ruff/rules/#flake8-todos-td + #'TID', # https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid +] + +# Exceptions to the linting rules + +# Ignore specific rules globally +ignore = [ + 'COM812', # https://docs.astral.sh/ruff/rules/missing-trailing-comma/ + # The following is replaced by 'D'/[tool.ruff.lint.pydocstyle] and [tool.pydoclint] 'DOC', # https://docs.astral.sh/ruff/rules/#pydoclint-doc + # Disable, as [tool.format_docstring] split one-line docstrings into the canonical multi-line layout + 'D200', # https://docs.astral.sh/ruff/rules/unnecessary-multiline-docstring/ +] + +# Ignore specific rules in certain files or directories +[tool.ruff.lint.per-file-ignores] +'*/__init__.py' = [ + 'F401', # re-exports are intentional in __init__.py +] +'tests/**' = [ + 'ANN', # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann + 'D', # https://docs.astral.sh/ruff/rules/#pydocstyle-d + 'DOC', # https://docs.astral.sh/ruff/rules/#pydoclint-doc + 'INP001', # https://docs.astral.sh/ruff/rules/implicit-namespace-package/ + 'S101', # https://docs.astral.sh/ruff/rules/assert/ ] +'docs/**' = [ + 'INP001', # https://docs.astral.sh/ruff/rules/implicit-namespace-package/ + 'T201', # https://docs.astral.sh/ruff/rules/print/ +] + +# Specific options for certain rules + +[tool.ruff.lint.flake8-tidy-imports] +# Disallow all relative imports +ban-relative-imports = 'all' [tool.ruff.lint.isort] +# Forces all from imports to appear on their own line force-single-line = true -[tool.tox] -legacy_tox_ini = """ -[tox] -isolated_build = True -envlist = py{3.11,3.12,3.13} -[gh-actions] -python = - 3.11: py311 - 3.12: py312 - 3.13: py313 -[gh-actions:env] -PLATFORM = - ubuntu-latest: linux - macos-latest: macos - windows-latest: 2022 -[testenv] -passenv = - CI - GITHUB_ACTIONS - GITHUB_ACTION - GITHUB_REF - GITHUB_REPOSITORY - GITHUB_HEAD_REF - GITHUB_RUN_ID - GITHUB_SHA - COVERAGE_FILE -deps = coverage -commands = - pip install -e '.[dev]' - pytest --cov --cov-report=xml -""" +[tool.ruff.lint.mccabe] +# Cyclomatic complexity threshold (default is 10) +max-complexity = 10 + +[tool.ruff.lint.pycodestyle] +# PEP 8 line length guidance: +# https://peps.python.org/pep-0008/#maximum-line-length +# Use 99 characters as the project-wide maximum for regular code lines. +# Use 72 characters for docstrings. +max-line-length = 128 # See also `line-length` in [tool.ruff] +max-doc-length = 128 +# max-doc-length = 72 + +[tool.ruff.lint.pydocstyle] +convention = 'numpy' + +[tool.ruff.lint.pylint] +# Ruff counts `self`/`cls` in max-args; traditional pylint does not. +# Setting 6 here matches pylint's default of 5 (excluding self). +max-args = 6 +max-positional-args = 6 + +############################# +# Configuration for pydoclint +############################# + +# 'pydoclint' -- Docstring linter, a faster alternative to +# 'darglint' or 'darglint2'. +# https://pypi.org/project/pydoclint/ + +# This is a more advanced docstring linter compared to Ruff's built-in +# docstring check rules D or DOC. For example, among many other things, +# it can check that arguments in the docstring, which are used by MkDocs +# and IDEs to render parameter documentation, remain synchronized with +# the parameter declarations in the code (in function's signature). + +[tool.pydoclint] +exclude = '\.' # Temporarily disable pydoclint until we are ready +style = 'numpy' +check-style-mismatch = true +check-arg-defaults = true +allow-init-docstring = true + +#################################### +# Configuration for format-docstring +#################################### + +# 'format-docstring' -- Code formatter for docstrings +# https://github.com/jsh9/format-docstring + +[tool.format_docstring] +exclude = '\.' # Temporarily disable format-docstring until we are ready +docstring_style = 'numpy' +line_length = 72 +fix_rst_backticks = true +verbose = 'default' diff --git a/src/easyreflectometry/__init__.py b/src/easyreflectometry/__init__.py index 6de988ac..8ff945d0 100644 --- a/src/easyreflectometry/__init__.py +++ b/src/easyreflectometry/__init__.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +"""EasyReflectometry library.""" + from importlib import metadata from .project import Project @@ -8,6 +13,6 @@ __version__ = '0.0.0' __all__ = [ - Project, - __version__, + 'Project', + '__version__', ] diff --git a/src/easyreflectometry/__version__.py b/src/easyreflectometry/__version__.py deleted file mode 100644 index bcd8d54e..00000000 --- a/src/easyreflectometry/__version__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '1.6.0' diff --git a/src/easyreflectometry/calculators/__init__.py b/src/easyreflectometry/calculators/__init__.py index 2411a89f..9f7bde45 100644 --- a/src/easyreflectometry/calculators/__init__.py +++ b/src/easyreflectometry/calculators/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import traceback from .calculator_base import CalculatorBase @@ -28,4 +31,4 @@ traceback.print_exc() print('Warning: refl1d is not installed') -__all__ = [CalculatorBase, CalculatorFactory] + imported_calculators +__all__ = ['CalculatorBase', 'CalculatorFactory'] + [c.__name__ for c in imported_calculators] diff --git a/src/easyreflectometry/calculators/bornagain/calculator.py b/src/easyreflectometry/calculators/bornagain/calculator.py index 06d86986..2ebb2c08 100644 --- a/src/easyreflectometry/calculators/bornagain/calculator.py +++ b/src/easyreflectometry/calculators/bornagain/calculator.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from easyscience.fitting.calculators.interface_factory import ItemContainer @@ -18,9 +20,7 @@ class BornAgain(CalculatorBase): - """ - Calculator for BornAgain - """ + """Calculator for BornAgain.""" name = 'BornAgain' @@ -45,23 +45,26 @@ class BornAgain(CalculatorBase): } def __init__(self): + """Init function.""" super().__init__() self._wrapper = BornAgainWrapper() def reset_storage(self) -> None: - """ - Reset the storage area of the calculator - """ + """Reset the storage area of the calculator.""" self._wrapper.reset_storage() def create(self, model: Material | Layer | Multilayer | Model) -> list[ItemContainer]: - """ - Creation function + """Creation function. - :param model: Object to be created - :type model: Union[Material, Layer, Item, Model] - :return: Item containers of the objects - :rtype: List[ItemContainer] + Parameters + ---------- + model : Material | Layer | Multilayer | Model + Object to be created. + + Returns + ------- + List[ItemContainer] + Item containers of the objects. """ r_list = [] t_ = type(model) @@ -130,52 +133,61 @@ def create(self, model: Material | Layer | Multilayer | Model) -> list[ItemConta return r_list def assign_material_to_layer(self, material_id: int, layer_id: int) -> None: - """ - Assign a material to a layer. - - :param material_name: The material name - :type material_name: str - :param layer_name: The layer name - :type layer_name: str + """Assign a material to a layer. + + Parameters + ---------- + layer_id : int + material_id : int + material_name : str + The material name. + layer_name : str + The layer name. """ self._wrapper.assign_material_to_layer(material_id, layer_id) def add_layer_to_item(self, layer_id: int, item_id: int) -> None: - """ - Add a layer to the item stack - - :param item_id: The item id - :type item_id: int - :param layer_id: The layer id - :type layer_id: int + """Add a layer to the item stack. + + Parameters + ---------- + item_id : int + The item id. + layer_id : int + The layer id. """ self._wrapper.add_layer_to_item(layer_id, item_id) def remove_layer_from_item(self, layer_id: int, item_id: int) -> None: - """ - Remove a layer from an item stack - - :param item_id: The item id - :param layer_id: The layer id + """Remove a layer from an item stack. + + Parameters + ---------- + item_id : int + The item id. + layer_id : int + The layer id. """ self._wrapper.remove_layer_from_item(layer_id, item_id) def add_item_to_model(self, item_id: int) -> None: - """ - Add a layer to the item stack + """Add a layer to the item stack. - :param item_id: The item id - :type item_id: int + Parameters + ---------- + item_id : int + The item id. """ self._wrapper.add_item(item_id) def remove_item_from_model(self, item_id: int) -> None: - """ - Remove a layer from the item stack - - :param item_id: The item id - :type item_id: int - :param layer_id: The layer id - :type layer_id: int + """Remove a layer from the item stack. + + Parameters + ---------- + item_id : int + The item id. + layer_id : int + The layer id. """ self._wrapper.remove_item(item_id) diff --git a/src/easyreflectometry/calculators/bornagain/wrapper.py b/src/easyreflectometry/calculators/bornagain/wrapper.py index 5ad3b985..b0baf9a9 100644 --- a/src/easyreflectometry/calculators/bornagain/wrapper.py +++ b/src/easyreflectometry/calculators/bornagain/wrapper.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import bornagain as ba import numpy as np @@ -14,6 +16,7 @@ class BornAgainWrapper(WrapperBase): def __init__(self): + """Init function.""" super().__init__() self.storage = { 'layer_material': {}, @@ -24,9 +27,7 @@ def __init__(self): } def reset_storage(self): - """ - Reset the storage area to blank. - """ + """Reset the storage area to blank.""" super().reset_storage() self.storage = { 'layer_material': {}, @@ -37,20 +38,23 @@ def reset_storage(self): } def create_material(self, name): - """ - Create a material using SLD. + """Create a material using SLD. - :param name: The name of the material - :type name: str + Parameters + ---------- + name : str + The name of the material. """ self.storage['material'][name] = ba.MaterialBySLD(str(name), 0.0, 0.0) def update_material(self, name, **kwargs): - """ - Update a material. + """Update a material. - :param name: The name of the material - :type name: str + Parameters + ---------- + **kwargs : + name : str + The name of the material. """ current_value = self.storage['material'][name].materialData() real = current_value.real @@ -64,40 +68,48 @@ def update_material(self, name, **kwargs): self.storage['material'][name] = ba.MaterialBySLD(str(name), real, imag) def get_material_value(self, name, key): - """ - A function to get a given material value - - :param name: The material name - :type name: str - :param key: The given value keys - :type name: str - :return: The desired value - :rtype: float + """A function to get a given material value. + + Parameters + ---------- + name : str + The material name. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ current_value = self.storage['material'][name].materialData() return getattr(current_value, key) / 1e-6 def create_layer(self, name): - """ - Create a layer using Slab. + """Create a layer using Slab. - :param name: The name of the layer - :type name: str + Parameters + ---------- + name : str + The name of the layer. """ self.storage['layer'][name] = ba.Layer(ba.MaterialBySLD('A', 0, 0)) self.storage['roughness'][name] = ba.LayerRoughness() def update_layer(self, name, **kwargs): - """ - Update a layer in a given item. + """Update a layer in a given item. - :param name: The layer name - :type name: str + Parameters + ---------- + **kwargs : + name : str + The layer name. """ if 'thickness' in kwargs.keys(): thickness = kwargs['thickness'] self.storage['layer'][name] = ba.Layer( - self.storage['material'][self.storage['layer_material'][name]], thickness * ba.angstrom + self.storage['material'][self.storage['layer_material'][name]], + thickness * ba.angstrom, ) if 'sigma' in kwargs.keys(): sigma = kwargs['sigma'] @@ -105,15 +117,19 @@ def update_layer(self, name, **kwargs): self.storage['roughness'][name].setSigma(sigma * ba.angstrom) def get_layer_value(self, name, key): - """ - A function to get a given layer value - - :param name: The layer name - :type name: str - :param key: The given value keys - :type name: str - :return: The desired value - :rtype: float + """A function to get a given layer value. + + Parameters + ---------- + name : str + The layer name. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ layer = self.storage['layer'][name] roughness = self.storage['roughness'][name] @@ -123,43 +139,48 @@ def get_layer_value(self, name, key): return roughness.getSigma() / ba.angstrom def create_item(self, name): - """ - Create an item. + """Create an item. - :param name: The name of the item - :type name: str + Parameters + ---------- + name : str + The name of the item. """ self.storage['item'][name] = [] self.storage['item_repeats'][name] = 1 def update_item(self, name, **kwargs): - """ - Update a layer. + """Update a layer. - :param name: The item name - :type name: str + Parameters + ---------- + **kwargs : + name : str + The item name. """ if 'repeats' in kwargs.keys(): self.storage['item_repeats'][name] = kwargs['repeats'] def get_item_value(self, name, key): - """ - A function to get a given item value - - :param name: The item name - :type name: str - :param key: The given value keys - :type name: str - :return: The desired value - :rtype: float + """A function to get a given item value. + + Parameters + ---------- + name : str + The item name. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ if key == 'repeats': return self.storage['item_repeats'][name] def create_model(self): - """ - Create a model for analysis - """ + """Create a model for analysis.""" self.storage['model'] = ba.Multilayer() self.storage['model'].setRoughnessModel(ba.RoughnessModel.NEVOT_CROCE) self.storage['model_items'] = [] @@ -168,65 +189,72 @@ def create_model(self): self.storage['model_parameters']['resolution'] = 0 def update_model(self, name, **kwargs): - """ - Update the non-structural parameters of the model - """ + """Update the non-structural parameters of the model.""" model = self.storage[name + '_parameters'] for key in kwargs.keys(): model[key] = kwargs[key] def get_model_value(self, name, key): - """ - A function to get a given model value + """A function to get a given model value. + + Parameters + ---------- + name : + key : str + The given value keys. - :param key: The given value keys - :type name: str - :return: The desired value - :rtype: float + Returns + ------- + float + The desired value. """ model = self.storage[name + '_parameters'] return model[key] def assign_material_to_layer(self, material_name, layer_name): - """ - Assign a material to a layer. + """Assign a material to a layer. - :param material_name: The material name - :type material_name: str - :param layer_name: The layer name - :type layer_name: str + Parameters + ---------- + material_name : str + The material name. + layer_name : str + The layer name. """ self.storage['layer_material'][layer_name] = material_name def add_layer_to_item(self, layer_name, item_name): - """ - Create a layer from the material of the same name, in a given item. + """Create a layer from the material of the same name, in a given item. - :param layer_name: The layer name - :type layer_name: int - :param item_name: The item name - :type item_name: int + Parameters + ---------- + layer_name : int + The layer name. + item_name : int + The item name. """ item = self.storage['item'][item_name] item.append(layer_name) def add_item(self, item_name): - """ - Add an item to the model. + """Add an item to the model. - :param item_name: items to add to model - :type item_name: str + Parameters + ---------- + item_name : str + Items to add to model. """ self.storage['model_items'].append(item_name) def remove_layer_from_item(self, layer_name, item_name): - """ - Remove a layer in a given item. + """Remove a layer in a given item. - :param layer_name: The layer name - :type layer_name: int - :param item_name: The item name - :type item_name: int + Parameters + ---------- + layer_name : int + The layer name. + item_name : int + The item name. """ layers_idx = self.storage['item'][item_name].index(layer_name) del self.storage['layer'][layer_name] @@ -234,11 +262,12 @@ def remove_layer_from_item(self, layer_name, item_name): del self.storage['layer_material'][layer_name] def remove_item(self, item_name): - """ - Remove a given item. + """Remove a given item. - :param item_name: The item name - :type item_name: int + Parameters + ---------- + item_name : int + The item name. """ item_idx = self.storage['model_items'].index(item_name) del self.storage['model_items'][item_idx] @@ -250,9 +279,17 @@ def remove_item(self, item_name): def calculate(self, q_array: np.ndarray) -> np.ndarray: """For a given q array calculate the corresponding reflectivity. - :param q_array: array of data points to be calculated - :param model_name: the model name - :return: reflectivity calculated at q + Parameters + ---------- + q_array : np.ndarray + Array of data points to be calculated. + model_name : + The model name. + + Returns + ------- + np.ndarray + Reflectivity calculated at q. """ # 3.5 sigma to sync with refnx n_sig = 3.5 @@ -261,7 +298,8 @@ def calculate(self, q_array: np.ndarray) -> np.ndarray: scan = ba.QSpecScan(q_array / ba.angstrom) scan.setAbsoluteQResolution( - distr, q_array / ba.angstrom * (self.storage['model_parameters']['resolution'] * 0.5 / 100) + distr, + q_array / ba.angstrom * (self.storage['model_parameters']['resolution'] * 0.5 / 100), ) simulation = ba.SpecularSimulation() @@ -286,13 +324,14 @@ def calculate(self, q_array: np.ndarray) -> np.ndarray: ) def sld_profile(self) -> np.ndarray: - """ - Return the scattering length density profile. + """Return the scattering length density profile. This is borrowed from the refnx implementation of the scattering length density. - :return: z and sld(z) - :rtype: tuple[np.ndarray, np.ndarray] + Returns + ------- + tuple[np.ndarray, np.ndarray] + Z and sld(z). """ number_of_layers = 0 for i in self.storage['model_items']: @@ -331,6 +370,7 @@ def sld_profile(self) -> np.ndarray: # use erf for roughness function, but step if the roughness is zero def step(z, scale=1, loc=0): + """Step function.""" new_z = z - loc f = np.ones_like(new_z) * 0.5 f[new_z <= -scale] = 0 diff --git a/src/easyreflectometry/calculators/calculator_base.py b/src/easyreflectometry/calculators/calculator_base.py index 7d1314cd..e2a92804 100644 --- a/src/easyreflectometry/calculators/calculator_base.py +++ b/src/easyreflectometry/calculators/calculator_base.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from abc import ABCMeta @@ -19,9 +22,7 @@ class CalculatorBase(SerializerComponent, metaclass=ABCMeta): - """ - This class is a template and defines all properties that a calculator should have. - """ + """This class is a template and defines all properties that a calculator should have.""" _calculators: list[CalculatorBase] = [] # class variable to store all calculators _material_link: dict[str, str] @@ -30,27 +31,36 @@ class CalculatorBase(SerializerComponent, metaclass=ABCMeta): _model_link: dict[str, str] def __init_subclass__(cls, is_abstract: bool = False, **kwargs) -> None: - r"""Initialise all subclasses so that they can be created in the factory - - :param is_abstract: Is this a subclass which shouldn't be dded - :param kwargs: key word arguments + r"""Initialise all subclasses so that they can be created in the factory. + + Parameters + ---------- + cls : + is_abstract : bool, optional + Is this a subclass which shouldn't be dded. By default, False. + **kwargs : + Key word arguments. """ super().__init_subclass__(**kwargs) if not is_abstract: cls._calculators.append(cls) def __init__(self): + """Init function.""" self._namespace = {} self._wrapper: WrapperBase def reset_storage(self) -> None: - """Reset the storage area of the calculator""" + r"""Reset the storage area of the calculator.""" self._wrapper.reset_storage() def create(self, model: Material | Layer | Multilayer | Model) -> list[ItemContainer]: - """Creation function + """Creation function. - :param model: Object to be created + Parameters + ---------- + model : Material | Layer | Multilayer | Model + Object to be created. """ r_list = [] t_ = type(model) @@ -122,72 +132,106 @@ def create(self, model: Material | Layer | Multilayer | Model) -> list[ItemConta def assign_material_to_layer(self, material_id: str, layer_id: str) -> None: """Assign a material to a layer. - :param material_id: The material name - :param layer_id: The layer name + Parameters + ---------- + material_id : str + The material name. + layer_id : str + The layer name. """ self._wrapper.assign_material_to_layer(material_id, layer_id) def add_layer_to_item(self, layer_id: str, item_id: str) -> None: - """Add a layer to the item stack - - :param item_id: The item id - :param layer_id: The layer id + """Add a layer to the item stack. + + Parameters + ---------- + item_id : str + The item id. + layer_id : str + The layer id. """ self._wrapper.add_layer_to_item(layer_id, item_id) def remove_layer_from_item(self, layer_id: str, item_id: str) -> None: - """Remove a layer from an item stack - - :param item_id: The item id - :param layer_id: The layer id + """Remove a layer from an item stack. + + Parameters + ---------- + item_id : str + The item id. + layer_id : str + The layer id. """ self._wrapper.remove_layer_from_item(layer_id, item_id) def add_item_to_model(self, item_id: str, model_id: str) -> None: - """Add a layer to the item stack - - :param item_id: The item id - :param model_id: The model id + """Add a layer to the item stack. + + Parameters + ---------- + item_id : str + The item id. + model_id : str + The model id. """ self._wrapper.add_item(item_id, model_id) def remove_item_from_model(self, item_id: str, model_id: str) -> None: - """Remove an item from the model - - :param item_id: The item id - :param model_id: The model id + """Remove an item from the model. + + Parameters + ---------- + item_id : str + The item id. + model_id : str + The model id. """ self._wrapper.remove_item(item_id, model_id) def reflectity_profile(self, x_array: np.ndarray, model_id: str) -> np.ndarray: """Determines the reflectivity profile for the given range and model. - :param x_array: points to be calculated at - :param model_id: The model id + Parameters + ---------- + x_array : np.ndarray + Points to be calculated at. + model_id : str + The model id. """ return self._wrapper.calculate(x_array, model_id) def sld_profile(self, model_id: str) -> tuple[np.ndarray, np.ndarray]: - """ - Return the scattering length density profile. + """Return the scattering length density profile. - :param model_id: The model id - :return: z and sld(z) + Parameters + ---------- + model_id : str + The model id. + + Returns + ------- + tuple[np.ndarray, np.ndarray] + z and sld(z). """ return self._wrapper.sld_profile(model_id) def set_resolution_function(self, resolution_function: Callable[[np.array], np.array]) -> None: + """Set resolution function.""" return self._wrapper.set_resolution_function(resolution_function) @property def include_magnetism(self): + """Include magnetism.""" return self._wrapper.magnetism @include_magnetism.setter def include_magnetism(self, magnetism: bool): - """ - Set the magnetism flag for the calculator + """Set the magnetism flag for the calculator. - :param magnetism: True if the calculator should include magnetism + Parameters + ---------- + magnetism : bool + True if the calculator should include magnetism. """ self._wrapper.magnetism = magnetism diff --git a/src/easyreflectometry/calculators/factory.py b/src/easyreflectometry/calculators/factory.py index 15e996fd..c3e1479c 100644 --- a/src/easyreflectometry/calculators/factory.py +++ b/src/easyreflectometry/calculators/factory.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + __author__ = 'github.com/wardsimon' from typing import Callable @@ -8,16 +11,20 @@ class CalculatorFactory(InterfaceFactoryTemplate): def __init__(self): + """Init function.""" super().__init__(interface_list=CalculatorBase._calculators) def reset_storage(self) -> None: + """Reset storage.""" return self().reset_storage() def sld_profile(self, model_id: str) -> tuple: + """Sld profile.""" return self().sld_profile(model_id) @property def fit_func(self) -> Callable: + """Fit func.""" """ Pass through to the underlying interfaces fitting function. @@ -32,6 +39,7 @@ def fit_func(self) -> Callable: #""" def __fit_func(*args, **kwargs): + """Fit func.""" return self().reflectity_profile(*args, **kwargs) return __fit_func diff --git a/src/easyreflectometry/calculators/refl1d/calculator.py b/src/easyreflectometry/calculators/refl1d/calculator.py index a472b7b5..2f5068de 100644 --- a/src/easyreflectometry/calculators/refl1d/calculator.py +++ b/src/easyreflectometry/calculators/refl1d/calculator.py @@ -1,13 +1,13 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from ..calculator_base import CalculatorBase from .wrapper import Refl1dWrapper class Refl1d(CalculatorBase): - """ - Calculator for refl1 - """ + """Calculator for refl1.""" name = 'refl1d' @@ -31,5 +31,6 @@ class Refl1d(CalculatorBase): } def __init__(self): + """Init function.""" super().__init__() self._wrapper = Refl1dWrapper() diff --git a/src/easyreflectometry/calculators/refl1d/wrapper.py b/src/easyreflectometry/calculators/refl1d/wrapper.py index e47cf052..7a07c917 100644 --- a/src/easyreflectometry/calculators/refl1d/wrapper.py +++ b/src/easyreflectometry/calculators/refl1d/wrapper.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Tuple @@ -17,18 +19,22 @@ class Refl1dWrapper(WrapperBase): def create_material(self, name: str): - """ - Create a material using SLD. + """Create a material using SLD. - :param name: The name of the material + Parameters + ---------- + name : str + The name of the material. """ self.storage['material'][name] = names.SLD(str(name)) def create_layer(self, name: str): - """ - Create a layer using Slab. + """Create a layer using Slab. - :param name: The name of the layer + Parameters + ---------- + name : str + The name of the layer. """ if self._magnetism: magnetism = names.Magnetism(rhoM=0.0, thetaM=0.0) @@ -37,10 +43,12 @@ def create_layer(self, name: str): self.storage['layer'][name] = names.Slab(name=str(name), magnetism=magnetism) def create_item(self, name: str): - """ - Create an item using Repeat. + """Create an item using Repeat. - :param name: The name of the item + Parameters + ---------- + name : str + The name of the item. """ self.storage['item'][name] = Repeat(names.Stack(names.Slab(names.SLD(), thickness=0, interface=0)), name=str(name)) del self.storage['item'][name].stack[0] @@ -48,8 +56,11 @@ def create_item(self, name: str): def update_layer(self, name: str, **kwargs): """Update a layer in a given item. - :param name: The layer name. - :param kwargs: + Parameters + ---------- + name : str + The layer name. + **kwargs : """ kwargs_no_magnetism = {k: v for k, v in kwargs.items() if k != 'magnetism_rhoM' and k != 'magnetism_thetaM'} super().update_layer(name, **kwargs_no_magnetism) @@ -58,10 +69,14 @@ def update_layer(self, name: str, **kwargs): self.storage['layer'][name].magnetism = magnetism def get_layer_value(self, name: str, key: str) -> float: - """A function to get a given layer value - - :param name: The layer name - :param key: The given value keys + """A function to get a given layer value. + + Parameters + ---------- + name : str + The layer name. + key : str + The given value keys. """ if key in ['magnetism_rhoM', 'magnetism_thetaM']: return getattr( @@ -70,78 +85,105 @@ def get_layer_value(self, name: str, key: str) -> float: return super().get_layer_value(name, key) def create_model(self, name: str): - """ - Create a model for analysis + """Create a model for analysis. - :param name: Name for the model + Parameters + ---------- + name : str + Name for the model. """ self.storage['model'][name] = {'scale': 1, 'bkg': 0, 'items': []} def update_model(self, name: str, **kwargs): - """ - Update the non-structural parameters of the model + """Update the non-structural parameters of the model. - :param name: Name of the model + Parameters + ---------- + **kwargs : + name : str + Name of the model. """ model = self.storage['model'][name] for key in kwargs.keys(): model[key] = kwargs[key] def get_model_value(self, name: str, key: str) -> float: - """ - A function to get a given model value - - :param name: Name of the model - :param key: The given value keys - :return: The desired value + """A function to get a given model value. + + Parameters + ---------- + name : str + Name of the model. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ model = self.storage['model'][name] return model[key] def assign_material_to_layer(self, material_name: str, layer_name: str): - """ - Assign a material to a layer. - - :param material_name: The material name - :param layer_name: The layer name + """Assign a material to a layer. + + Parameters + ---------- + material_name : str + The material name. + layer_name : str + The layer name. """ self.storage['layer'][layer_name].material = self.storage['material'][material_name] def add_layer_to_item(self, layer_name: str, item_name: str): - """ - Create a layer from the material of the same name, in a given item. - - :param layer_name: The layer name - :param item_name: The item name + """Create a layer from the material of the same name, in a given item. + + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ item = self.storage['item'][item_name] item.stack.add(self.storage['layer'][layer_name]) def add_item(self, item_name: str, model_name: str): - """ - Add an item to the model. - - :param item_name: items to add to model - :param model_name: name for the model + """Add an item to the model. + + Parameters + ---------- + item_name : str + Items to add to model. + model_name : str + Name for the model. """ self.storage['model'][model_name]['items'].append(self.storage['item'][item_name]) def remove_layer_from_item(self, layer_name: str, item_name: str): - """ - Remove a layer in a given item. - - :param layer_name: The layer name - :param item_name: The item name + """Remove a layer in a given item. + + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ layer_idx = list(self.storage['item'][item_name].stack).index(self.storage['layer'][layer_name]) del self.storage['item'][item_name].stack[layer_idx] def remove_item(self, item_name: str, model_name: str): - """ - Remove a given item. - - :param item_name: The item name - :param model_name: The model name + """Remove a given item. + + Parameters + ---------- + item_name : str + The item name. + model_name : str + The model name. """ item_idx = self.storage['model'][model_name]['items'].index(self.storage['item'][item_name]) del self.storage['model'][model_name]['items'][item_idx] @@ -150,9 +192,17 @@ def remove_item(self, item_name: str, model_name: str): def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: """For a given q array calculate the corresponding reflectivity. - :param q_array: array of data points to be calculated - :param model_name: the model name - :return: reflectivity calculated at q + Parameters + ---------- + q_array : np.ndarray + Array of data points to be calculated. + model_name : str + The model name. + + Returns + ------- + np.ndarray + Reflectivity calculated at q. """ sample = _build_sample(self.storage, model_name) dq_array = self._resolution_function.smearing(q_array) @@ -197,11 +247,17 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: return reflectivity def sld_profile(self, model_name: str) -> Tuple[np.ndarray, np.ndarray]: - """ - Return the scattering length density profile. + """Return the scattering length density profile. + + Parameters + ---------- + model_name : str + The model name. + + Returns + ------- - :param model_name: the model name - :return: z and sld(z) + Z and sld(z). """ sample = _build_sample(self.storage, model_name) probe = _get_probe( @@ -216,6 +272,7 @@ def sld_profile(self, model_name: str) -> Tuple[np.ndarray, np.ndarray]: def _get_oversampling_q(q_array: np.ndarray, dq_array: np.ndarray, oversampling_factor: int) -> np.ndarray: + """Get oversampling q.""" argmin = np.argmin(q_array) # index of the smallest q element argmax = np.argmax(q_array) # index of the largest q element return np.linspace( @@ -233,6 +290,7 @@ def _get_probe( oversampling_factor: int = 1, magnetism: bool = False, ) -> names.QProbe: + """Get probe.""" probe = names.QProbe( Q=q_array, dQ=dq_array, @@ -258,6 +316,7 @@ def _get_polarized_probe( oversampling_factor: int = 1, all_polarizations: bool = False, ) -> names.PolarizedNeutronQProbe: + """Get polarized probe.""" four_probes = [] for i in range(4): if i == 0 or all_polarizations: @@ -281,6 +340,7 @@ def _get_polarized_probe( def _build_sample(storage: dict, model_name: str) -> names.Stack: + """Build sample.""" sample = names.Stack() # -1 to reverse the order for i in storage['model'][model_name]['items'][::-1]: diff --git a/src/easyreflectometry/calculators/refnx/calculator.py b/src/easyreflectometry/calculators/refnx/calculator.py index 2a5b45b0..1362bad2 100644 --- a/src/easyreflectometry/calculators/refnx/calculator.py +++ b/src/easyreflectometry/calculators/refnx/calculator.py @@ -1,13 +1,13 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from ..calculator_base import CalculatorBase from .wrapper import RefnxWrapper class Refnx(CalculatorBase): - """ - Calculator for refnx - """ + """Calculator for refnx.""" name = 'refnx' @@ -31,5 +31,6 @@ class Refnx(CalculatorBase): } def __init__(self): + """Init function.""" super().__init__() self._wrapper = RefnxWrapper() diff --git a/src/easyreflectometry/calculators/refnx/wrapper.py b/src/easyreflectometry/calculators/refnx/wrapper.py index d2290877..3742d727 100644 --- a/src/easyreflectometry/calculators/refnx/wrapper.py +++ b/src/easyreflectometry/calculators/refnx/wrapper.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Tuple @@ -13,53 +15,68 @@ class RefnxWrapper(WrapperBase): @property def include_magnetism(self) -> bool: + """Include magnetism.""" return self._magnetism @include_magnetism.setter def include_magnetism(self, magnetism: bool) -> None: """Set the magnetism flag. - :param magnetism: The magnetism flag + Parameters + ---------- + magnetism : bool + The magnetism flag. """ raise NotImplementedError('Magnetism is not supported by refnx') def create_material(self, name: str): - """ - Create a material using SLD. + """Create a material using SLD. - :param name: The name of the material + Parameters + ---------- + name : str + The name of the material. """ self.storage['material'][name] = reflect.SLD(0, name=name) def create_layer(self, name: str): - """ - Create a layer using Slab. + """Create a layer using Slab. - :param name: The name of the layer + Parameters + ---------- + name : str + The name of the layer. """ self.storage['layer'][name] = reflect.Slab(0, 0, 0, name=name) def create_item(self, name: str): - """ - Create an item using Stack. + """Create an item using Stack. - :param name: The name of the item + Parameters + ---------- + name : str + The name of the item. """ self.storage['item'][name] = reflect.Stack(name=name) def create_model(self, name: str): - """ - Create a model for analysis + """Create a model for analysis. - :param name: Name for the model + Parameters + ---------- + name : str + Name for the model. """ self.storage['model'][name] = reflect.ReflectModel(reflect.Structure()) def update_model(self, name: str, **kwargs): - """ - Update the non-structural parameters of the model + """Update the non-structural parameters of the model. - :param name: Name for the model + Parameters + ---------- + **kwargs : + name : str + Name for the model. """ model = self.storage['model'][name] for key in kwargs.keys(): @@ -67,61 +84,83 @@ def update_model(self, name: str, **kwargs): setattr(item, 'value', kwargs[key]) def get_model_value(self, name: str, key: str) -> float: - """ - A function to get a given model value + """A function to get a given model value. + + Parameters + ---------- + name : str + Name for the model. + key : str + The given value keys. - :param name: Name for the model - :param key: The given value keys - :return: The desired value + Returns + ------- + float + The desired value. """ model = self.storage['model'][name] item = getattr(model, key) return getattr(item, 'value') def assign_material_to_layer(self, material_name: str, layer_name: str): - """ - Assign a material to a layer. + """Assign a material to a layer. - :param material_name: The material name - :param layer_name: The layer name + Parameters + ---------- + material_name : str + The material name. + layer_name : str + The layer name. """ self.storage['layer'][layer_name].sld = self.storage['material'][material_name] def add_layer_to_item(self, layer_name: str, item_name: str): - """ - Create a layer from the material of the same name, in a given item. + """Create a layer from the material of the same name, in a given item. - :param layer_name: The layer name - :param item_name: The item name + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ item = self.storage['item'][item_name] item.append(self.storage['layer'][layer_name]) def add_item(self, item_name: str, model_name: str): - """ - Add an item to the model. + """Add an item to the model. - :param item_name: items to add to model - :param model_name: Name for the model + Parameters + ---------- + item_name : str + Items to add to model. + model_name : str + Name for the model. """ self.storage['model'][model_name].structure.components.append(self.storage['item'][item_name]) def remove_layer_from_item(self, layer_name: str, item_name: str): - """ - Remove a layer in a given item. + """Remove a layer in a given item. - :param layer_name: The layer name - :param item_name: The item name + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ layer_idx = self.storage['item'][item_name].components.index(self.storage['layer'][layer_name]) del self.storage['item'][item_name].components[layer_idx] def remove_item(self, item_name: str, model_name: str): - """ - Remove a given item. + """Remove a given item. - :param item_name: The item name - :param model_name: Name of the model + Parameters + ---------- + item_name : str + The item name. + model_name : str + Name of the model. """ item_idx = self.storage['model'][model_name].structure.components.index(self.storage['item'][item_name]) del self.storage['model'][model_name].structure.components[item_idx] @@ -130,9 +169,17 @@ def remove_item(self, item_name: str, model_name: str): def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: """For a given q array calculate the corresponding reflectivity. - :param q_array: array of data points to be calculated - :param model_name: the model name - :return: reflectivity calculated at q + Parameters + ---------- + q_array : np.ndarray + Array of data points to be calculated. + model_name : str + The model name. + + Returns + ------- + np.ndarray + Reflectivity calculated at q. """ structure = _remove_unecessary_stacks(self.storage['model'][model_name].structure) model = reflect.ReflectModel( @@ -151,22 +198,33 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: return model(x=q_array, x_err=dq_vector) def sld_profile(self, model_name: str) -> Tuple[np.ndarray, np.ndarray]: - """ - Return the scattering length density profile. + """Return the scattering length density profile. - :param model_name: Name for the model - :return: z and sld(z) + Parameters + ---------- + model_name : str + Name for the model. + + Returns + ------- + + Z and sld(z). """ return _remove_unecessary_stacks(self.storage['model'][model_name].structure).sld_profile() def _remove_unecessary_stacks(current_structure: reflect.Structure) -> reflect.Structure: - """ - Removed unnecessary reflect.Stack objects from the structure. + """Removed unnecessary reflect.Stack objects from the structure. + + Parameters + ---------- + current_structure : reflect.Structure + The current structure. - :param current_structure: The current structure - :return: The structre without the unnecessary Stacks - :rtype: reflect.structure + Returns + ------- + reflect.structure + The structre without the unnecessary Stacks. """ structure = [] for i in current_structure.components: diff --git a/src/easyreflectometry/calculators/wrapper_base.py b/src/easyreflectometry/calculators/wrapper_base.py index 0755ff64..dc53ceca 100644 --- a/src/easyreflectometry/calculators/wrapper_base.py +++ b/src/easyreflectometry/calculators/wrapper_base.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from abc import abstractmethod import numpy as np @@ -31,7 +34,10 @@ def reset_storage(self): def create_material(self, name: str): """Create a material using SLD. - :param name: The name of the material + Parameters + ---------- + name : str + The name of the material. """ ... @@ -39,7 +45,10 @@ def create_material(self, name: str): def create_layer(self, name: str): """Create a layer using Slab. - :param name: The name of the layer + Parameters + ---------- + name : str + The name of the layer. """ ... @@ -47,34 +56,46 @@ def create_layer(self, name: str): def create_item(self, name: str): """Create an item using Stack. - :param name: The name of the item + Parameters + ---------- + name : str + The name of the item. """ ... @abstractmethod def create_model(self, name: str): - """Create a model for analysis + """Create a model for analysis. - :param name: Name for the model + Parameters + ---------- + name : str + Name for the model. """ ... @abstractmethod def update_model(self, name: str, **kwargs): - """Update the non-structural parameters of the model - - :param name: Name for the model - :param kwargs: + """Update the non-structural parameters of the model. + Parameters + ---------- + name : str + Name for the model. + **kwargs : """ ... @abstractmethod def get_model_value(self, name: str, key: str) -> float: - """A function to get a given model value - - :param name: Name for the model - :param key: The given value keys + """A function to get a given model value. + + Parameters + ---------- + name : str + Name for the model. + key : str + The given value keys. """ ... @@ -82,8 +103,12 @@ def get_model_value(self, name: str, key: str) -> float: def assign_material_to_layer(self, material_name: str, layer_name: str): """Assign a material to a layer. - :param material_name: The material name - :param layer_name: The layer name + Parameters + ---------- + material_name : str + The material name. + layer_name : str + The layer name. """ ... @@ -91,8 +116,12 @@ def assign_material_to_layer(self, material_name: str, layer_name: str): def add_layer_to_item(self, layer_name: str, item_name: str): """Create a layer from the material of the same name, in a given item. - :param layer_name: The layer name - :param item_name: The item name + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ ... @@ -100,8 +129,12 @@ def add_layer_to_item(self, layer_name: str, item_name: str): def add_item(self, item_name: str, model_name: str): """Add an item to the model. - :param item_name: items to add to model - :param model_name: Name for the model + Parameters + ---------- + item_name : str + Items to add to model. + model_name : str + Name for the model. """ ... @@ -109,8 +142,12 @@ def add_item(self, item_name: str, model_name: str): def remove_layer_from_item(self, layer_name: str, item_name: str): """Remove a layer in a given item. - :param layer_name: The layer name - :param item_name: The item name + Parameters + ---------- + layer_name : str + The layer name. + item_name : str + The item name. """ ... @@ -118,8 +155,12 @@ def remove_layer_from_item(self, layer_name: str, item_name: str): def remove_item(self, item_name: str, model_name: str): """Remove a given item. - :param item_name: The item name - :param model_name: Name of the model + Parameters + ---------- + item_name : str + The item name. + model_name : str + Name of the model. """ ... @@ -127,9 +168,17 @@ def remove_item(self, item_name: str, model_name: str): def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: """For a given q array calculate the corresponding reflectivity. - :param q_array: array of data points to be calculated - :param model_name: the model name - :return: reflectivity calculated at q + Parameters + ---------- + q_array : np.ndarray + Array of data points to be calculated. + model_name : str + The model name. + + Returns + ------- + np.ndarray + Reflectivity calculated at q. """ ... @@ -137,15 +186,27 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: def sld_profile(self, model_name: str) -> tuple[np.ndarray, np.ndarray]: """Return the scattering length density profile. - :param model_name: Name for the model - :return: z and sld(z) + Parameters + ---------- + model_name : str + Name for the model. + + Returns + ------- + tuple[np.ndarray, np.ndarray] + Z and sld(z). """ ... def update_material(self, name: str, **kwargs): """Update a material. - :param name: The name of the material + Parameters + ---------- + name : str + The name of the material. + **kwargs : + Key-value pairs of attributes to update. """ material = self.storage['material'][name] for key in kwargs.keys(): @@ -153,11 +214,19 @@ def update_material(self, name: str, **kwargs): setattr(item, 'value', kwargs[key]) def get_material_value(self, name: str, key: str) -> float: - """A function to get a given material value - - :param name: The material name - :param key: The given value keys - :return: The desired value + """A function to get a given material value. + + Parameters + ---------- + name : str + The material name. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ material = self.storage['material'][name] item = getattr(material, key) @@ -166,8 +235,11 @@ def get_material_value(self, name: str, key: str) -> float: def update_layer(self, name: str, **kwargs): """Update a layer in a given item. - :param name: The layer name. - :param kwargs: + Parameters + ---------- + name : str + The layer name. + **kwargs : """ layer = self.storage['layer'][name] for key in kwargs.keys(): @@ -175,10 +247,14 @@ def update_layer(self, name: str, **kwargs): setattr(ii, 'value', kwargs[key]) def get_layer_value(self, name: str, key: str) -> float: - """A function to get a given layer value - - :param name: The layer name - :param key: The given value keys + """A function to get a given layer value. + + Parameters + ---------- + name : str + The layer name. + key : str + The given value keys. """ layer = self.storage['layer'][name] ii = getattr(layer, key) @@ -187,7 +263,11 @@ def get_layer_value(self, name: str, key: str) -> float: def update_item(self, name: str, **kwargs): """Update a layer. - :param name: The item name + Parameters + ---------- + **kwargs : + name : str + The item name. """ item = self.storage['item'][name] for key in kwargs.keys(): @@ -195,11 +275,19 @@ def update_item(self, name: str, **kwargs): setattr(ii, 'value', kwargs[key]) def get_item_value(self, name: str, key: str) -> float: - """A function to get a given item value - - :param name: The item name - :param key: The given value keys - :return: The desired value + """A function to get a given item value. + + Parameters + ---------- + name : str + The item name. + key : str + The given value keys. + + Returns + ------- + float + The desired value. """ item = self.storage['item'][name] item = getattr(item, key) @@ -208,18 +296,25 @@ def get_item_value(self, name: str, key: str) -> float: def set_resolution_function(self, resolution_function: ResolutionFunction) -> None: """Set the resolution function for the calculator. - :param resolution_function: The resolution function + Parameters + ---------- + resolution_function : ResolutionFunction + The resolution function. """ self._resolution_function = resolution_function @property def magnetism(self) -> bool: + """Magnetism function.""" return self._magnetism @magnetism.setter def magnetism(self, magnetism: bool) -> None: """Set the magnetism flag. - :param magnetism: The magnetism flag + Parameters + ---------- + magnetism : bool + The magnetism flag. """ self._magnetism = magnetism diff --git a/src/easyreflectometry/data/__init__.py b/src/easyreflectometry/data/__init__.py index 194f0d31..0d058120 100644 --- a/src/easyreflectometry/data/__init__.py +++ b/src/easyreflectometry/data/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .data_store import DataSet1D from .data_store import ProjectData from .measurement import load diff --git a/src/easyreflectometry/data/data_store.py b/src/easyreflectometry/data/data_store.py index 948382d7..b0cf001f 100644 --- a/src/easyreflectometry/data/data_store.py +++ b/src/easyreflectometry/data/data_store.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + __author__ = 'github.com/wardsimon' from collections.abc import Sequence @@ -16,6 +19,7 @@ class ProjectData(SerializerComponent): def __init__(self, name='DataStore', exp_data=None, sim_data=None): + """Init function.""" self.name = name if exp_data is None: exp_data = DataStore(name='Exp Datastore') @@ -27,31 +31,39 @@ def __init__(self, name='DataStore', exp_data=None, sim_data=None): class DataStore(Sequence, SerializerComponent): def __init__(self, *args, name='DataStore'): + """Init function.""" self.name = name self.items = list(args) self.show_legend = False def __getitem__(self, i: int) -> T: + """Getitem function.""" return self.items.__getitem__(i) def __len__(self) -> int: + """Len function.""" return len(self.items) def __setitem__(self, key, value): + """Setitem function.""" self.items[key] = value def __delitem__(self, key): + """Delitem function.""" del self.items[key] def append(self, *args): + """Append function.""" self.items.append(*args) def as_dict(self, skip: list = []) -> dict: + """As dict.""" this_dict = super(DataStore, self).as_dict(self, skip=skip) this_dict['items'] = [item.as_dict() for item in self.items if hasattr(item, 'as_dict')] @classmethod def from_dict(cls, d): + """From dict.""" items = d['items'] del d['items'] obj = cls.from_dict(d) @@ -61,10 +73,12 @@ def from_dict(cls, d): @property def experiments(self): + """Experiments function.""" return [self[idx] for idx in range(len(self)) if self[idx].is_experiment] @property def simulations(self): + """Simulations function.""" return [self[idx] for idx in range(len(self)) if self[idx].is_simulation] @@ -81,6 +95,7 @@ def __init__( y_label: str = 'y', auto_background: bool = True, ): + """Init function.""" self._model = model if y is not None and model is not None and auto_background: self._model.background = max(np.min(y), 1e-10) @@ -119,22 +134,28 @@ def __init__( @property def model(self) -> 'Model': # delay type checking until runtime (quotes) + """Model function.""" return self._model @model.setter def model(self, new_model: 'Model') -> None: + """Model function.""" self._model = new_model @property def is_experiment(self) -> bool: + """Is experiment.""" return self._model is not None @property def is_simulation(self) -> bool: + """Is simulation.""" return self._model is None def data_points(self) -> tuple[float, float, float, float]: + """Data points.""" return zip(self.x, self.y, self.ye, self.xe) def __repr__(self) -> str: + """Repr function.""" return "1D DataStore of '{:s}' Vs '{:s}' with {} data points".format(self.x_label, self.y_label, len(self.x)) diff --git a/src/easyreflectometry/data/measurement.py b/src/easyreflectometry/data/measurement.py index df4064b6..12117162 100644 --- a/src/easyreflectometry/data/measurement.py +++ b/src/easyreflectometry/data/measurement.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import os from typing import TextIO @@ -14,7 +16,10 @@ def load(fname: Union[TextIO, str]) -> sc.DataGroup: """Load data from an ORSO .ort file. - :param fname: The file to be read. + Parameters + ---------- + fname : Union[TextIO, str] + The file to be read. """ try: return load_data_from_orso_file(fname) @@ -40,6 +45,7 @@ def load_as_dataset(fname: Union[TextIO, str]) -> DataSet1D: def extract_orso_title(data_group: sc.DataGroup, data_name: str) -> str | None: + """Extract orso title.""" try: header = data_group['attrs'][data_name]['orso_header'] title = header.values.get('data_source', {}).get('experiment', {}).get('title') @@ -54,7 +60,10 @@ def extract_orso_title(data_group: sc.DataGroup, data_name: str) -> str | None: def _load_txt(fname: Union[TextIO, str]) -> sc.DataGroup: """Load data from a simple txt file. - :param fname: The path for the file to be read. + Parameters + ---------- + fname : Union[TextIO, str] + The path for the file to be read. """ # fname can have either a space or a comma as delimiter # Determine the delimiter used in the file diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 0750beb5..78f74e68 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import warnings @@ -18,11 +20,20 @@ def _validate_objective(objective: str) -> str: """Validate and resolve the objective string. - :param objective: The objective mode string. - :type objective: str - :return: Resolved objective string ('auto' becomes 'hybrid'). - :rtype: str - :raises ValueError: If the objective is not one of the valid options. + Parameters + ---------- + objective : str + The objective mode string. + + Raises + ------ + ValueError : + If the objective is not one of the valid options. + + Returns + ------- + str + Resolved objective string ('auto' becomes 'hybrid'). """ if objective not in _VALID_OBJECTIVES: raise ValueError(f'Unknown objective {objective!r}. Valid options: {_VALID_OBJECTIVES}') @@ -46,17 +57,22 @@ def _prepare_fit_arrays( Note: ``variances`` here means σ² (the scipp convention), not σ. - :param x_vals: Independent variable values. - :type x_vals: np.ndarray - :param y_vals: Observed dependent variable values. - :type y_vals: np.ndarray - :param variances: Variance (σ²) of each observed point. - :type variances: np.ndarray - :param objective: One of 'legacy_mask', 'hybrid', 'mighell'. - :type objective: str - :return: Tuple of (x_out, y_eff, weights, stats) where stats is a dict - with keys 'valid', 'mighell_substituted', 'masked'. - :rtype: tuple[np.ndarray, np.ndarray, np.ndarray, dict] + Parameters + ---------- + x_vals : np.ndarray + Independent variable values. + y_vals : np.ndarray + Observed dependent variable values. + variances : np.ndarray + Variance (σ²) of each observed point. + objective : str + One of 'legacy_mask', 'hybrid', 'mighell'. + + Returns + ------- + tuple[np.ndarray, np.ndarray, np.ndarray, dict] + Tuple of (x_out, y_eff, weights, stats) where stats is a dict + with keys 'valid', 'mighell_substituted', 'masked'. """ n = len(y_vals) zero_mask = variances <= 0.0 @@ -71,7 +87,12 @@ def _prepare_fit_arrays( weights = 1.0 / np.sqrt(variances[valid]) else: weights = np.array([]) - stats = {'valid': n_valid, 'mighell_substituted': 0, 'masked': n_zero, 'transformed_all_points': False} + stats = { + 'valid': n_valid, + 'mighell_substituted': 0, + 'masked': n_zero, + 'transformed_all_points': False, + } return x_out, y_eff, weights, stats # hybrid or mighell @@ -143,18 +164,24 @@ def __init__(self, *args: Model, objective: str = 'hybrid'): which will populate the :py:class:`sc.DataGroup` appropriately after the fitting is performed. - :param args: Reflectometry model(s). - :param objective: Zero-variance handling strategy. One of + Parameters + ---------- + *args : Model + Reflectometry model(s). + objective : str, optional + Zero-variance handling strategy. One of ``'hybrid'`` (default, Mighell for zero-variance, WLS otherwise), ``'mighell'`` (Mighell transform for all points), ``'legacy_mask'`` (drop zero-variance points), - ``'auto'`` (alias for ``'hybrid'``). - :type objective: str + ``'auto'`` (alias for ``'hybrid'``). By default, 'hybrid'. """ # This lets the unique_name be passed with the fit_func. def func_wrapper(func, unique_name): + """Func wrapper.""" + def wrapped(*args, **kwargs): + """Wrapped function.""" return func(*args, unique_name, **kwargs) return wrapped @@ -169,21 +196,20 @@ def wrapped(*args, **kwargs): def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup: """Perform the fitting and populate the DataGroups with the result. - :param data: DataGroup to be fitted to and populated. - :type data: sc.DataGroup - :param id: Unused parameter kept for backward compatibility. - :type id: int - :param objective: Per-call override for the zero-variance objective. - If ``None``, uses the instance default set at construction. - :type objective: str or None - :return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics. - :rtype: sc.DataGroup - - :note: Under the ``mighell`` objective all points are transformed, - so ``reduced_chi`` is not a classical chi-square statistic. - Under ``hybrid``, only zero-variance points are transformed; - when they are a small fraction of the data the chi-square - remains approximately classical. + Parameters + ---------- + data : sc.DataGroup + DataGroup to be fitted to and populated. + id : int, optional + Unused parameter kept for backward compatibility. By default, 0. + objective : str | None, optional + Per-call override for the zero-variance objective. + If ``None``, uses the instance default set at construction. By default, None. + + Returns + ------- + sc.DataGroup + A new DataGroup with fitted model curves, SLD profiles, and fit statistics. """ obj = _validate_objective(objective) if objective is not None else self._objective @@ -236,7 +262,9 @@ def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> if 'attrs' in new_data: new_data['attrs'][f'R_{id}_model'] = {'model': sc.scalar(self._models[i].as_dict())} new_data['coords'][f'z_{id}'] = sc.array( - dims=[f'z_{id}'], values=sld_profile[0], unit=(1 / new_data['coords'][f'Qz_{id}'].unit).unit + dims=[f'z_{id}'], + values=sld_profile[0], + unit=(1 / new_data['coords'][f'Qz_{id}'].unit).unit, ) original = original_arrays[i] sigma_classical = np.sqrt(np.clip(original['variances'], 0.0, None)) @@ -246,15 +274,13 @@ def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> objective_chi2 = float(result[i].chi2) objective_reduced_chi = _fit_result_reduced_chi(result[i], np.size(result[i].x)) - self._classical_fit_metrics.append( - { - 'classical_chi2': classical_chi2, - 'classical_reduced_chi': classical_reduced_chi, - 'objective_chi2': objective_chi2, - 'objective_reduced_chi': objective_reduced_chi, - 'n_classical_points': n_classical_points, - } - ) + self._classical_fit_metrics.append({ + 'classical_chi2': classical_chi2, + 'classical_reduced_chi': classical_reduced_chi, + 'objective_chi2': objective_chi2, + 'objective_reduced_chi': objective_reduced_chi, + 'n_classical_points': n_classical_points, + }) new_data['objective_chi2'] = objective_chi2 new_data['objective_reduced_chi'] = objective_reduced_chi @@ -267,14 +293,19 @@ def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> def fit_single_data_set_1d(self, data: DataSet1D, objective: str | None = None) -> FitResults: """Perform fitting on a single 1D dataset. - :param data: The 1D dataset to fit. Note that ``data.ye`` stores + Parameters + ---------- + data : DataSet1D + The 1D dataset to fit. Note that ``data.ye`` stores variances (σ²), not standard deviations. - :type data: DataSet1D - :param objective: Per-call override for the zero-variance objective. - If ``None``, uses the instance default set at construction. - :type objective: str or None - :return: Fit results from the minimizer. - :rtype: FitResults + objective : str | None, optional + Per-call override for the zero-variance objective. + If ``None``, uses the instance default set at construction. By default, None. + + Returns + ------- + FitResults + Fit results from the minimizer. """ obj = _validate_objective(objective) if objective is not None else self._objective @@ -372,20 +403,27 @@ def objective_reduced_chi(self) -> float | None: return self.reduced_chi def switch_minimizer(self, minimizer: AvailableMinimizers) -> None: - """ - Switch the minimizer for the fitting. + """Switch the minimizer for the fitting. - :param minimizer: Minimizer to be switched to + Parameters + ---------- + minimizer : AvailableMinimizers + Minimizer to be switched to. """ self.easy_science_multi_fitter.switch_minimizer(minimizer) def _flatten_list(this_list: list) -> list: - """ - Flatten nested lists. + """Flatten nested lists. - :param this_list: List to be flattened + Parameters + ---------- + this_list : list + List to be flattened. - :return: Flattened list + Returns + ------- + list + Flattened list. """ return np.array([item for sublist in this_list for item in sublist]) diff --git a/src/easyreflectometry/limits.py b/src/easyreflectometry/limits.py index 691f86e3..001bba64 100644 --- a/src/easyreflectometry/limits.py +++ b/src/easyreflectometry/limits.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np from easyscience.variable import Parameter @@ -9,10 +12,12 @@ def apply_default_limits(parameter: Parameter, kind: str) -> None: """Apply default min/max to a parameter if current bounds are infinite. - :param parameter: The parameter to adjust. - :type parameter: Parameter - :param kind: One of 'thickness', 'roughness', 'sld', 'isld', 'scale'. - :type kind: str + Parameters + ---------- + parameter : Parameter + The parameter to adjust. + kind : str + One of 'thickness', 'roughness', 'sld', 'isld', 'scale'. """ if not parameter.independent: return diff --git a/src/easyreflectometry/main.py b/src/easyreflectometry/main.py index 043d72c1..2f7737e0 100644 --- a/src/easyreflectometry/main.py +++ b/src/easyreflectometry/main.py @@ -1,7 +1,11 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from easyreflectometry.calculators import CalculatorFactory def main(): + """Main function.""" factory = CalculatorFactory() print(f'Available calculators: {factory.available_interfaces}') diff --git a/src/easyreflectometry/model/__init__.py b/src/easyreflectometry/model/__init__.py index 6246b2d8..698b5a0c 100644 --- a/src/easyreflectometry/model/__init__.py +++ b/src/easyreflectometry/model/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .model import Model from .model_collection import ModelCollection from .resolution_functions import LinearSpline diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index 7f651fa2..b1aedf85 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -1,6 +1,7 @@ -from __future__ import annotations +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause -__author__ = 'github.com/arm61' +from __future__ import annotations import copy from numbers import Number @@ -43,11 +44,23 @@ }, } -COLORS = ['#0173B2', '#DE8F05', '#029E73', '#D55E00', '#CC78BC', '#CA9161', '#FBAFE4', '#949494', '#ECE133', '#56B4E9'] +COLORS = [ + '#0173B2', + '#DE8F05', + '#029E73', + '#D55E00', + '#CC78BC', + '#CA9161', + '#FBAFE4', + '#949494', + '#ECE133', + '#56B4E9', +] class Model(BaseObj): """Model is the class that represents the experiment. + It is used to store the information about the experiment and to perform the calculations. """ @@ -70,13 +83,24 @@ def __init__( ): """Constructor. - :param sample: The sample being modelled. - :param scale: Scaling factor of profile. - :param background: Linear background magnitude. - :param name: Name of the model, defaults to 'Model'. - :param resolution_function: Resolution function, defaults to PercentageFwhm. - :param interface: Calculator interface, defaults to `None`. - + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + color : str, optional + By default, COLORS[0]. + sample : Union[Sample, None], optional + The sample being modelled. By default, None. + scale : Union[Parameter, Number, None], optional + Scaling factor of profile. By default, None. + background : Union[Parameter, Number, None], optional + Linear background magnitude. By default, None. + name : str, optional + Name of the model. By default, 'Model'. + resolution_function : Union[ResolutionFunction, None], optional + Resolution function. By default, None. + interface : + Calculator interface. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -107,7 +131,10 @@ def __init__( def add_assemblies(self, *assemblies: list[BaseAssembly]) -> None: """Add assemblies to the model sample. - :param assemblies: Assemblies to add to model sample. + Parameters + ---------- + *assemblies : list[BaseAssembly] + Assemblies to add to model sample. """ if not assemblies: self.sample.add_assembly() @@ -125,7 +152,11 @@ def add_assemblies(self, *assemblies: list[BaseAssembly]) -> None: def duplicate_assembly(self, index: int) -> None: """Duplicate a given item or layer in a sample. - :param idx: Index of the item or layer to duplicate + Parameters + ---------- + index : int + idx : + Index of the item or layer to duplicate. """ self.sample.duplicate_assembly(index) if self.interface is not None: @@ -134,7 +165,11 @@ def duplicate_assembly(self, index: int) -> None: def remove_assembly(self, index: int) -> None: """Remove an assembly from the model. - :param idx: Index of the item to remove. + Parameters + ---------- + index : int + idx : + Index of the item to remove. """ assembly_unique_name = self.sample[index].unique_name self.sample.remove_assembly(index) @@ -150,8 +185,10 @@ def is_default(self) -> bool: def is_default(self, value: bool) -> None: """Set whether this model is a default placeholder. - :param value: True if the model is a default placeholder. - :type value: bool + Parameters + ---------- + value : bool + True if the model is a default placeholder. """ self._is_default = value @@ -169,9 +206,7 @@ def resolution_function(self, resolution_function: ResolutionFunction) -> None: @property def interface(self): - """ - Get the current interface of the object - """ + """Get the current interface of the object.""" return self._interface @interface.setter @@ -209,9 +244,13 @@ def __repr__(self) -> str: def as_dict(self, skip: Optional[list[str]] = None) -> dict: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ if skip is None: skip = [] @@ -233,12 +272,7 @@ def as_orso(self) -> dict: @classmethod def from_dict(cls, passed_dict: dict) -> Model: - """ - Create a Model from a dictionary. - - :param this_dict: dictionary of the Model - :return: Model - """ + """Create a Model from a dictionary.""" # Causes circular import if imported at the top from easyreflectometry.calculators import CalculatorFactory diff --git a/src/easyreflectometry/model/model_collection.py b/src/easyreflectometry/model/model_collection.py index b3c0bd2d..1a1b7e88 100644 --- a/src/easyreflectometry/model/model_collection.py +++ b/src/easyreflectometry/model/model_collection.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import List @@ -12,6 +15,7 @@ # Needs to be a function, elements are added to the global_object.map def DEFAULT_ELEMENTS(interface): + """Default elements.""" return (Model(interface),) @@ -26,6 +30,7 @@ def __init__( next_color_index: Optional[int] = None, **kwargs, ): + """Init function.""" if not models: if populate_if_none: models = DEFAULT_ELEMENTS(interface) @@ -49,7 +54,10 @@ def __init__( def add_model(self, model: Optional[Model] = None): """Add a model to the collection. - :param model: Model to add. + Parameters + ---------- + model : Optional[Model], optional + Model to add. By default, None. """ if model is None: model = Model(name='Model', interface=self.interface, color=self._current_color()) @@ -58,7 +66,10 @@ def add_model(self, model: Optional[Model] = None): def duplicate_model(self, index: int): """Duplicate a model in the collection. - :param index: Model to duplicate. + Parameters + ---------- + index : int + Model to duplicate. """ to_be_duplicated = self[index] duplicate = Model.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) @@ -66,6 +77,7 @@ def duplicate_model(self, index: int): self.append(duplicate) def as_dict(self, skip: List[str] | None = None) -> dict: + """As dict.""" this_dict = super().as_dict(skip=skip) this_dict['populate_if_none'] = self.populate_if_none this_dict['next_color_index'] = self._next_color_index @@ -73,11 +85,7 @@ def as_dict(self, skip: List[str] | None = None) -> dict: @classmethod def from_dict(cls, this_dict: dict) -> ModelCollection: - """ - Create an instance of a collection from a dictionary. - - :param data: The dictionary for the collection - """ + """Create an instance of a collection from a dictionary.""" collection_dict = this_dict.copy() # We need to call from_dict on the base class to get the models dict_data = collection_dict.pop('data') @@ -102,14 +110,17 @@ def from_dict(cls, this_dict: dict) -> ModelCollection: return collection def append(self, model: Model) -> None: # type: ignore[override] + """Append function.""" self._append_internal(model, advance=True) def _append_internal(self, model: Model, advance: bool) -> None: + """Append internal.""" super().append(model) if advance: self._advance_color_index() def _advance_color_index(self) -> None: + """Advance color index.""" if not COLORS: self._next_color_index = 0 return @@ -119,6 +130,7 @@ def _advance_color_index(self) -> None: self._next_color_index = (self._next_color_index + 1) % len(COLORS) def _current_color(self) -> str: + """Current color.""" if not COLORS: raise ValueError('No colors defined for models.') if self._next_color_index is None: diff --git a/src/easyreflectometry/model/resolution_functions.py b/src/easyreflectometry/model/resolution_functions.py index 2a6e5c8c..ee0933e2 100644 --- a/src/easyreflectometry/model/resolution_functions.py +++ b/src/easyreflectometry/model/resolution_functions.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """Resolution functions for the resolution of the experiment. When a percentage is provided we assume that the resolution is a Gaussian distribution with a FWHM of the percentage of the q value. @@ -26,51 +29,68 @@ def as_dict(self, skip: Optional[List[str]] = None) -> dict: ... @classmethod def from_dict(cls, data: dict) -> ResolutionFunction: + """Smearing function.""" if data['smearing'] == 'PercentageFwhm': return PercentageFwhm(data['constant']) if data['smearing'] == 'LinearSpline': return LinearSpline(data['q_data_points'], data['fwhm_values']) if data['smearing'] == 'Pointwise': - return Pointwise([data['q_data_points'], data['R_data_points'], data['sQz_data_points']]) + return Pointwise([ + data['q_data_points'], + data['R_data_points'], + data['sQz_data_points'], + ]) raise ValueError('Unknown resolution function type') class PercentageFwhm(ResolutionFunction): def __init__(self, constant: Union[None, float] = None): + """Init function.""" if constant is None: constant = DEFAULT_RESOLUTION_FWHM_PERCENTAGE self.constant = constant def smearing(self, q: Union[np.array, float]) -> np.array: + """Smearing function.""" return np.ones(np.array(q).size) * self.constant def as_dict( self, skip: Optional[List[str]] = None ) -> dict[str, str]: # skip is kept for consistency of the as_dict signature + """As dict.""" return {'smearing': 'PercentageFwhm', 'constant': self.constant} class LinearSpline(ResolutionFunction): def __init__(self, q_data_points: np.array, fwhm_values: np.array): + """Init function.""" self.q_data_points = q_data_points self.fwhm_values = fwhm_values def smearing(self, q: Union[np.array, float]) -> np.array: + """Smearing function.""" return np.interp(q, self.q_data_points, self.fwhm_values) def as_dict( self, skip: Optional[List[str]] = None ) -> dict[str, str]: # skip is kept for consistency of the as_dict signature - return {'smearing': 'LinearSpline', 'q_data_points': list(self.q_data_points), 'fwhm_values': list(self.fwhm_values)} + """As dict.""" + return { + 'smearing': 'LinearSpline', + 'q_data_points': list(self.q_data_points), + 'fwhm_values': list(self.fwhm_values), + } # add pointwise smearing funtion class Pointwise(ResolutionFunction): def __init__(self, q_data_points: list[np.ndarray]): + """Init function.""" self.q_data_points = q_data_points self.q = None def smearing(self, q: Union[np.ndarray, float] = None) -> np.ndarray: + """Smearing function.""" Qz = self.q_data_points[0] R = self.q_data_points[1] sQz = self.q_data_points[2] @@ -87,6 +107,7 @@ def smearing(self, q: Union[np.ndarray, float] = None) -> np.ndarray: def as_dict( self, skip: Optional[List[str]] = None ) -> dict[str, str]: # skip is kept for consistency of the as_dict signature + """As dict.""" return { 'smearing': 'Pointwise', 'q_data_points': list(self.q_data_points[0]), @@ -95,6 +116,7 @@ def as_dict( } def gaussian_smearing(self, qt, Qz, R, sQz): + """Gaussian smearing.""" weights = np.exp(-0.5 * ((qt - Qz) / sQz) ** 2) if np.sum(weights) == 0 or not np.isfinite(np.sum(weights)): return np.sum(R) @@ -102,9 +124,7 @@ def gaussian_smearing(self, qt, Qz, R, sQz): return np.sum(R * weights) / np.sum(weights) def apply_smooth_smearing(self, Qz, R, sQzs): - """ - Apply smooth resolution smearing using convolution with Gaussian kernel. - """ + """Apply smooth resolution smearing using convolution with Gaussian kernel.""" if self.q is None: R_smeared = np.zeros_like(Qz) else: diff --git a/src/easyreflectometry/orso_utils.py b/src/easyreflectometry/orso_utils.py index 494ed248..aa320933 100644 --- a/src/easyreflectometry/orso_utils.py +++ b/src/easyreflectometry/orso_utils.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import logging import warnings @@ -49,8 +52,7 @@ def load_data_from_orso_file(fname: str) -> sc.DataGroup: def load_orso_model(orso_data) -> Sample: - """ - Load a model from an ORSO file and return a Sample object. + """Load a model from an ORSO file and return a Sample object. The ORSO file .ort contains information about the sample, saved as a simple "stack" string, e.g. 'air | m1 | SiO2 | Si'. @@ -61,11 +63,20 @@ def load_orso_model(orso_data) -> Sample: - Middle layers -> 'Loaded layer' Multilayer assembly (parameters enabled) - Last layer -> Subphase assembly (thickness=0 fixed, roughness enabled) - :param orso_data: Parsed ORSO dataset list (as returned by ``orso.load_orso``). - :type orso_data: list - :return: An EasyReflectometry Sample object. - :rtype: Sample - :raises ValueError: If ORSO layers could not be resolved or fewer than 2 layers. + Parameters + ---------- + orso_data : list + Parsed ORSO dataset list (as returned by ``orso.load_orso``). + + Raises + ------ + ValueError : + If ORSO layers could not be resolved or fewer than 2 layers. + + Returns + ------- + Sample + An EasyReflectometry Sample object. """ # Extract stack string and layer definitions from ORSO sample model sample_model = orso_data[0].info.data_source.sample.model @@ -134,7 +145,7 @@ def load_orso_model(orso_data) -> Sample: def _convert_orso_layer_to_erl(layer): - """Helper function to convert an ORSO layer to an EasyReflectometry layer""" + r"""Helper function to convert an ORSO layer to an EasyReflectometry laye.""" material = layer.material # Prefer original_name for material name, fall back to formula if available m_name = layer.original_name if layer.original_name is not None else material.formula @@ -157,7 +168,7 @@ def _get_sld_values(material, material_name): Note: ORSO stores SLD in absolute units (A^-2), but the internal representation uses 10^-6 A^-2. When reading directly from ORSO, we multiply by 1e6 to convert. - When calculating from mass density, MaterialDensity already returns the correct units. + When calculating from mass density, MaterialDensity already returns the correct units.. """ if material.sld is None and material.mass_density is not None: # Calculate SLD from mass density @@ -196,10 +207,15 @@ def _get_sld_values(material, material_name): def load_orso_data(orso_data) -> DataSet1D: """Convert parsed ORSO dataset objects into a scipp DataGroup. - :param orso_data: Parsed ORSO dataset list (as returned by ``orso.load_orso``). - :type orso_data: list - :return: A scipp DataGroup with data, coords, and attrs. - :rtype: sc.DataGroup + Parameters + ---------- + orso_data : list + Parsed ORSO dataset list (as returned by ``orso.load_orso``). + + Returns + ------- + sc.DataGroup + A scipp DataGroup with data, coords, and attrs. """ data = {} coords = {} diff --git a/src/easyreflectometry/plot.py b/src/easyreflectometry/plot.py index a88a89bf..3a0aaa26 100644 --- a/src/easyreflectometry/plot.py +++ b/src/easyreflectometry/plot.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import matplotlib.pyplot as plt import scipp as sc @@ -8,10 +10,12 @@ def plot(data: sc.DataGroup) -> None: - """ - A general plotting function for easyreflectometry. + """A general plotting function for easyreflectometry. - :param data: the DataGroup to be plotted. + Parameters + ---------- + data : sc.DataGroup + The DataGroup to be plotted. """ if len([i for i in list(data.keys()) if 'SLD' in i]) == 0: plot_sld = False @@ -41,7 +45,14 @@ def plot(data: sc.DataGroup) -> None: ) plot_model_data.data *= sc.scalar(10.0**i, unit=plot_model_data.unit) plot_model_data.coords[f'Qz_{refl_num}'].variances = None - sc.plot(plot_model_data, ax=ax1, norm='log', linestyle='--', color=color_cycle[i], marker='') + sc.plot( + plot_model_data, + ax=ax1, + norm='log', + linestyle='--', + color=color_cycle[i], + marker='', + ) except KeyError: pass ax1.autoscale(True) diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 7e1ab3c9..5127ad16 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import datetime import json import logging @@ -43,6 +46,7 @@ class Project: def __init__(self): + """Init function.""" self._info = self._default_info() self._path_project_parent = Path(os.path.expanduser('~')) self._models = ModelCollection(populate_if_none=False, unique_name='project_models') @@ -68,6 +72,7 @@ def __init__(self): self._with_experiments = False def reset(self): + """Reset function.""" del self._models del self._materials global_object.map._clear() @@ -140,40 +145,48 @@ def _sync_layer_parameter_state(self, parameter: Parameter, kind: str, disabled_ @property def q_min(self): + """Q min.""" if self._q_min is None: return Q_MIN return self._q_min @q_min.setter def q_min(self, value: float) -> None: + """Q min.""" self._q_min = value @property def q_max(self): + """Q max.""" if self._q_max is None: return Q_MAX return self._q_max @q_max.setter def q_max(self, value: float) -> None: + """Q max.""" self._q_max = value @property def q_resolution(self): + """Q resolution.""" if self._q_resolution is None: return Q_RESOLUTION return self._q_resolution @q_resolution.setter def q_resolution(self, value: int) -> None: + """Q resolution.""" self._q_resolution = value @property def current_material_index(self) -> Optional[int]: + """Current material index.""" return self._current_material_index @current_material_index.setter def current_material_index(self, value: int) -> None: + """Current material index.""" if value < 0 or value >= len(self._materials): raise ValueError(f'Index {value} out of range') if self._current_material_index != value: @@ -181,10 +194,12 @@ def current_material_index(self, value: int) -> None: @property def current_model_index(self) -> Optional[int]: + """Current model index.""" return self._current_model_index @current_model_index.setter def current_model_index(self, value: int) -> None: + """Current model index.""" if value < 0 or value >= len(self._models): raise ValueError(f'Index {value} out of range') if self._current_model_index != value: @@ -194,10 +209,12 @@ def current_model_index(self, value: int) -> None: @property def current_assembly_index(self) -> Optional[int]: + """Current assembly index.""" return self._current_assembly_index @current_assembly_index.setter def current_assembly_index(self, value: int) -> None: + """Current assembly index.""" if value < 0 or value >= len(self._models[self._current_model_index].sample): raise ValueError(f'Index {value} out of range') if self._current_assembly_index != value: @@ -206,10 +223,12 @@ def current_assembly_index(self, value: int) -> None: @property def current_layer_index(self) -> Optional[int]: + """Current layer index.""" return self._current_layer_index @current_layer_index.setter def current_layer_index(self, value: int) -> None: + """Current layer index.""" if value < 0 or value >= len(self._models[self._current_model_index].sample[self._current_assembly_index].layers): raise ValueError(f'Index {value} out of range') if self._current_layer_index != value: @@ -217,10 +236,12 @@ def current_layer_index(self, value: int) -> None: @property def current_experiment_index(self) -> Optional[int]: + """Current experiment index.""" return self._current_experiment_index @current_experiment_index.setter def current_experiment_index(self, value: int) -> None: + """Current experiment index.""" if value < 0 or value >= len(self._experiments): raise ValueError(f'Index {value} out of range') if self._current_experiment_index != value: @@ -230,21 +251,26 @@ def current_experiment_index(self, value: int) -> None: @property def created(self) -> bool: + """Created function.""" return self._created @property def path(self): + """Path function.""" return self._path_project_parent / self._info['name'] def set_path_project_parent(self, path: Union[Path, str]): + """Set path project parent.""" self._path_project_parent = Path(path) @property def models(self) -> ModelCollection: + """Models function.""" return self._models @models.setter def models(self, models: ModelCollection) -> None: + """Models function.""" self._replace_collection(models, self._models) # Use setter to update indicies for current model, assembly and layer self.current_model_index = 0 @@ -255,6 +281,7 @@ def models(self, models: ModelCollection) -> None: @property def fitter(self) -> MultiFitter: + """Fitter function.""" if len(self._models): if (self._fitter is None) or (self._fitter_model_index != self._current_model_index): self._fitter = MultiFitter(self._models[self._current_model_index]) @@ -264,10 +291,12 @@ def fitter(self) -> MultiFitter: @property def calculator(self) -> str: + """Calculator function.""" return self._calculator.current_interface_name @calculator.setter def calculator(self, calculator: str) -> None: + """Calculator function.""" if calculator == self._calculator.current_interface_name: return @@ -282,47 +311,61 @@ def calculator(self, calculator: str) -> None: @property def minimizer(self) -> AvailableMinimizers: + """Minimizer function.""" if self._fitter is not None: return self._fitter.easy_science_multi_fitter.minimizer.enum return self._minimizer_selection @minimizer.setter def minimizer(self, minimizer: AvailableMinimizers) -> None: + """Minimizer function.""" old_name = getattr(self._minimizer_selection, 'name', str(self._minimizer_selection)) new_name = getattr(minimizer, 'name', str(minimizer)) - logger.info('Minimizer changed from %s to %s (fitter active: %s)', old_name, new_name, self._fitter is not None) + logger.info( + 'Minimizer changed from %s to %s (fitter active: %s)', + old_name, + new_name, + self._fitter is not None, + ) self._minimizer_selection = minimizer if self._fitter is not None: self._fitter.easy_science_multi_fitter.switch_minimizer(minimizer) @property def experiments(self) -> Dict[int, DataSet1D]: + """Experiments function.""" return self._experiments @experiments.setter def experiments(self, experiments: Dict[int, DataSet1D]) -> None: + """Experiments function.""" self._experiments = experiments @property def path_json(self): + """Path json.""" return self.path / 'project.json' def get_index_air(self) -> int: + """Get index air.""" if 'Air' not in [material.name for material in self._materials]: self._materials.add_material(Material(name='Air', sld=0.0, isld=0.0)) return [material.name for material in self._materials].index('Air') def get_index_si(self) -> int: + """Get index si.""" if 'Si' not in [material.name for material in self._materials]: self._materials.add_material(Material(name='Si', sld=2.07, isld=0.0)) return [material.name for material in self._materials].index('Si') def get_index_sio2(self) -> int: + """Get index sio2.""" if 'SiO2' not in [material.name for material in self._materials]: self._materials.add_material(Material(name='SiO2', sld=3.47, isld=0.0)) return [material.name for material in self._materials].index('SiO2') def get_index_d2o(self) -> int: + """Get index d2o.""" if 'D2O' not in [material.name for material in self._materials]: self._materials.add_material(Material(name='D2O', sld=6.36, isld=0.0)) return [material.name for material in self._materials].index('D2O') @@ -351,10 +394,15 @@ def set_sample_from_orso(self, sample: Sample) -> None: This is a convenience helper for the ORSO import pipeline where a complete :class:`~easyreflectometry.sample.Sample` is constructed elsewhere. - :param sample: Sample to set as the project's (single) model. - :type sample: easyreflectometry.sample.Sample - :return: ``None``. - :rtype: None + Parameters + ---------- + sample : Sample + Sample to set as the project's (single) model. + + Returns + ------- + None + ``None``. """ model = Model(sample=sample) self.models = ModelCollection([model]) @@ -369,10 +417,15 @@ def add_sample_from_orso(self, sample: Sample) -> None: After adding the model, :attr:`current_model_index` is updated to point to the newly added model. - :param sample: Sample to add as a new model. - :type sample: easyreflectometry.sample.Sample - :return: ``None``. - :rtype: None + Parameters + ---------- + sample : Sample + Sample to add as a new model. + + Returns + ------- + None + ``None``. """ if sample is None: raise ValueError('The ORSO file does not contain a valid sample model definition.') @@ -393,10 +446,15 @@ def replace_models_from_orso(self, sample: Sample) -> None: model is created from *sample*, assigned to the project's calculator, and the material collection is rebuilt from the new model only. - :param sample: Sample to set as the project's only model. - :type sample: easyreflectometry.sample.Sample - :return: ``None``. - :rtype: None + Parameters + ---------- + sample : Sample + Sample to set as the project's only model. + + Returns + ------- + None + ``None``. """ if sample is None: raise ValueError('The ORSO file does not contain a valid sample model definition.') @@ -427,11 +485,18 @@ def _apply_experiment_metadata( ) -> None: """Set experiment name from ORSO title and configure the resolution function. - :param path: Path to the experiment data file. - :param experiment: The loaded experiment dataset to configure. - :param fallback_name: Name to use when no ORSO title is available. - :param data_group: Pre-loaded scipp DataGroup (avoids reloading the file). - :param data_key: Specific dataset key to use for title extraction (e.g. ``'R_1'``). + Parameters + ---------- + path : Union[Path, str] + Path to the experiment data file. + experiment : DataSet1D + The loaded experiment dataset to configure. + fallback_name : str + Name to use when no ORSO title is available. + data_group : + Pre-loaded scipp DataGroup (avoids reloading the file). By default, None. + data_key : Optional[str], optional + Specific dataset key to use for title extraction (e.g. ``'R_1'``). By default, None. """ # Prefer ORSO title when available (keeps UI descriptive) title = None @@ -456,8 +521,12 @@ def _apply_resolution_function( ) -> None: """Set the resolution function on *model* based on variance data in *experiment*. - :param experiment: The experiment whose variance data drives the choice. - :param model: The model whose resolution function is set. + Parameters + ---------- + experiment : DataSet1D + The experiment whose variance data drives the choice. + model : Model + The model whose resolution function is set. """ model.resolution_function = PercentageFwhm(5.0) @@ -468,6 +537,7 @@ def _auto_set_background(experiment: DataSet1D) -> None: experiment.model.background = max(np.min(experiment.y), 1e-10) def load_new_experiment(self, path: Union[Path, str]) -> None: + """Load new experiment.""" new_experiment = load_as_dataset(str(path)) new_index = len(self._experiments) @@ -485,8 +555,15 @@ def load_new_experiment(self, path: Union[Path, str]) -> None: def count_datasets_in_file(self, path: Union[Path, str]) -> int: """Return the number of datasets contained in the file at *path*. - :param path: Path to the data file. - :return: Number of datasets found; 1 if the file cannot be introspected. + Parameters + ---------- + path : Union[Path, str] + Path to the data file. + + Returns + ------- + int + Number of datasets found; 1 if the file cannot be introspected. """ try: data_group = load_data_from_orso_file(str(path)) @@ -502,8 +579,15 @@ def load_all_experiments_from_file(self, path: Union[Path, str]) -> int: currently selected. Falls back to :meth:`load_new_experiment` for single-dataset files or on any loading error. - :param path: Path to the data file. - :return: Number of experiments that were added. + Parameters + ---------- + path : Union[Path, str] + Path to the data file. + + Returns + ------- + int + Number of experiments that were added. """ try: data_group = load_data_from_orso_file(str(path)) @@ -547,6 +631,7 @@ def load_all_experiments_from_file(self, path: Union[Path, str]) -> int: return len(data_keys) def load_experiment_for_model_at_index(self, path: Union[Path, str], index: Optional[int] = 0) -> None: + """Load experiment for model at index.""" experiment = load_as_dataset(str(path)) self._apply_experiment_metadata(path, experiment, f'Experiment {index}') @@ -557,6 +642,7 @@ def load_experiment_for_model_at_index(self, path: Union[Path, str], index: Opti self._apply_resolution_function(experiment, self._models[index]) def sld_data_for_model_at_index(self, index: int = 0) -> DataSet1D: + """Sld data for model at index.""" self.models[index].interface = self._calculator sld = self.models[index].interface().sld_profile(self._models[index].unique_name) return DataSet1D( @@ -566,6 +652,7 @@ def sld_data_for_model_at_index(self, index: int = 0) -> DataSet1D: ) def sample_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.array] = None) -> DataSet1D: + """Sample data for model at index.""" original_resolution_function = self.models[index].resolution_function self.models[index].resolution_function = PercentageFwhm(0) reflectivity_data = self.model_data_for_model_at_index(index, q_range) @@ -574,6 +661,7 @@ def sample_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.ar return reflectivity_data def model_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.array] = None) -> DataSet1D: + """Model data for model at index.""" if q_range is None: q_range = np.linspace(self.q_min, self.q_max, self.q_resolution) self.models[index].interface = self._calculator @@ -585,18 +673,38 @@ def model_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.arr ) def experimental_data_for_model_at_index(self, index: int = 0) -> DataSet1D: + """Experimental data for model at index.""" if index in self._experiments.keys(): return self._experiments[index] else: raise IndexError(f'No experiment data for model at index {index}') def default_model(self): + """Default model.""" self._replace_collection(MaterialCollection(interface=self._calculator), self._materials) layers = [ - Layer(material=self._materials[0], thickness=0.0, roughness=0.0, name='Vacuum Layer', interface=self._calculator), - Layer(material=self._materials[1], thickness=100.0, roughness=3.0, name='D2O Layer', interface=self._calculator), - Layer(material=self._materials[2], thickness=0.0, roughness=1.2, name='Si Layer', interface=self._calculator), + Layer( + material=self._materials[0], + thickness=0.0, + roughness=0.0, + name='Vacuum Layer', + interface=self._calculator, + ), + Layer( + material=self._materials[1], + thickness=100.0, + roughness=3.0, + name='D2O Layer', + interface=self._calculator, + ), + Layer( + material=self._materials[2], + thickness=0.0, + roughness=1.2, + name='Si Layer', + interface=self._calculator, + ), ] assemblies = [ Multilayer(layers[0], name='Superphase', interface=self._calculator), @@ -611,10 +719,15 @@ def default_model(self): def is_default_model(self, index: int) -> bool: """Check if the model at the given index is a default model. - :param index: Index of the model to check. - :type index: int - :return: True if the model was created as a default placeholder. - :rtype: bool + Parameters + ---------- + index : int + Index of the model to check. + + Returns + ------- + bool + True if the model was created as a default placeholder. """ if index < 0 or index >= len(self._models): return False @@ -630,10 +743,17 @@ def remove_model_at_index(self, index: int) -> None: Adjusts the current model index if necessary. - :param index: Index of the model to remove. - :type index: int - :raises IndexError: If the index is out of range. - :raises ValueError: If trying to remove the last remaining model. + Parameters + ---------- + index : int + Index of the model to remove. + + Raises + ------ + IndexError : + If the index is out of range. + ValueError : + If trying to remove the last remaining model. """ if index < 0 or index >= len(self._models): raise IndexError(f'Model index {index} out of range') @@ -668,18 +788,21 @@ def remove_model_at_index(self, index: int) -> None: self._current_layer_index = 0 def add_material(self, material: MaterialCollection) -> None: + """Add material.""" if material in self._materials: print(f'WARNING: Material {material} is already in material collection') else: self._materials.append(material) def remove_material(self, index: int) -> None: + """Remove material.""" if self._materials[index] in self._get_materials_in_models(): print(f'ERROR: Material {self._materials[index]} is used in models') else: self._materials.pop(index) def _default_info(self): + """Default info.""" return dict( name='DefaultEasyReflectometryProject', short_description='Reflectometry, 1D', @@ -687,6 +810,7 @@ def _default_info(self): ) def create(self): + """Create function.""" if not os.path.exists(self.path): os.makedirs(self.path) os.makedirs(self.path / 'experiments') @@ -696,6 +820,7 @@ def create(self): print(f'ERROR: Directory {self.path} already exists') def save_as_json(self, overwrite=False): + """Save as json.""" if self.path_json.exists() and overwrite: print(f'File already exists {self.path_json}. Overwriting...') self.path_json.unlink() @@ -708,6 +833,7 @@ def save_as_json(self, overwrite=False): print(exception) def load_from_json(self, path: Optional[Union[Path, str]] = None): + """Load from json.""" if path is None: path = self.path_json path = Path(path) @@ -722,6 +848,7 @@ def load_from_json(self, path: Optional[Union[Path, str]] = None): print(f'ERROR: File {path} does not exist') def as_dict(self, include_materials_not_in_model=False): + """As dict.""" project_dict = {} project_dict['info'] = self._info project_dict['with_experiments'] = self._with_experiments @@ -743,6 +870,7 @@ def as_dict(self, include_materials_not_in_model=False): return project_dict def _as_dict_add_materials_not_in_model_dict(self, project_dict: dict): + """As dict add materials not in model dict.""" materials_not_in_model = [] for material in self._materials: if material not in self._get_materials_in_models(): @@ -751,18 +879,24 @@ def _as_dict_add_materials_not_in_model_dict(self, project_dict: dict): project_dict['materials_not_in_model'] = MaterialCollection(materials_not_in_model).as_dict(skip=['interface']) def _as_dict_add_experiments(self, project_dict: dict): + """As dict add experiments.""" project_dict['experiments'] = {} project_dict['experiments_models'] = {} project_dict['experiments_names'] = {} for key, experiment in self._experiments.items(): - project_dict['experiments'][key] = [list(experiment.x), list(experiment.y), list(experiment.ye)] + project_dict['experiments'][key] = [ + list(experiment.x), + list(experiment.y), + list(experiment.ye), + ] if experiment.xe is not None: project_dict['experiments'][key].append(list(experiment.xe)) project_dict['experiments_models'][key] = experiment.model.name project_dict['experiments_names'][key] = experiment.name def from_dict(self, project_dict: dict): + """From dict.""" keys = list(project_dict.keys()) self._info = project_dict['info'] self._with_experiments = project_dict['with_experiments'] @@ -786,6 +920,7 @@ def from_dict(self, project_dict: dict): resolve_all_parameter_dependencies(self) def _from_dict_extract_experiments(self, project_dict: dict) -> Dict[int, DataSet1D]: + """From dict extract experiments.""" experiments = {} for key in project_dict['experiments'].keys(): experiments[int(key)] = DataSet1D( @@ -800,6 +935,7 @@ def _from_dict_extract_experiments(self, project_dict: dict) -> Dict[int, DataSe return experiments def _get_materials_in_models(self) -> MaterialCollection: + """Get materials in models.""" materials_in_model = MaterialCollection(populate_if_none=False) for model in self._models: for assembly in model.sample: @@ -808,6 +944,7 @@ def _get_materials_in_models(self) -> MaterialCollection: return materials_in_model def _replace_collection(self, src_collection: BaseCollection, dst_collection: BaseCollection) -> None: + """Replace collection.""" # Clear the destination collection for i in range(len(dst_collection)): dst_collection.pop(0) @@ -816,4 +953,5 @@ def _replace_collection(self, src_collection: BaseCollection, dst_collection: Ba dst_collection.append(element) def _timestamp_modification(self): + """Timestamp modification.""" self._info['modified'] = datetime.datetime.now().strftime('%d.%m.%Y %H:%M') diff --git a/src/easyreflectometry/sample/__init__.py b/src/easyreflectometry/sample/__init__.py index 4991b975..e6f347ad 100644 --- a/src/easyreflectometry/sample/__init__.py +++ b/src/easyreflectometry/sample/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .assemblies.base_assembly import BaseAssembly from .assemblies.bilayer import Bilayer from .assemblies.gradient_layer import GradientLayer diff --git a/src/easyreflectometry/sample/assemblies/__init__.py b/src/easyreflectometry/sample/assemblies/__init__.py new file mode 100644 index 00000000..4e798e20 --- /dev/null +++ b/src/easyreflectometry/sample/assemblies/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyreflectometry/sample/assemblies/base_assembly.py b/src/easyreflectometry/sample/assemblies/base_assembly.py index 68486805..39cb2b18 100644 --- a/src/easyreflectometry/sample/assemblies/base_assembly.py +++ b/src/easyreflectometry/sample/assemblies/base_assembly.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Any from typing import Optional @@ -8,6 +11,7 @@ class BaseAssembly(BaseCore): """Assembly of layers. + The front layer (front_layer) is the layer the neutron beam starts in, it has an index of 0. The back layer (back_layer) is the final layer from which the unreflected neutron beam is transmitted, its index number depends on the number of finite layers in the system, but it might be accessed at index -1. @@ -38,6 +42,7 @@ def __init__( @property def type(self) -> str: """Get type of the assembly. + Needed by the GUI. """ return self._type @@ -53,7 +58,10 @@ def front_layer(self) -> Optional[Layer]: def front_layer(self, layer: Layer) -> None: """Set the front layer in the assembly. - :param layer: Layer to set as the front layer. + Parameters + ---------- + layer : Layer + Layer to set as the front layer. """ if len(self.layers) == 0: self.layers.append(layer) @@ -72,7 +80,10 @@ def back_layer(self) -> Optional[Layer]: def back_layer(self, layer: Layer) -> None: """Set the back layer in the assembly. - :param layer: Layer to set as the back layer. + Parameters + ---------- + layer : Layer + Layer to set as the back layer. """ if len(self.layers) == 0: @@ -83,18 +94,14 @@ def back_layer(self, layer: Layer) -> None: self.layers[-1] = layer def _setup_thickness_constraints(self) -> None: - """ - Setup thickness constraint, front layer is the deciding layer - """ + """Setup thickness constraint, front layer is the deciding layer.""" independent_param = self.front_layer.thickness for i in range(1, len(self.layers)): self.layers[i].thickness.make_dependent_on(dependency_expression='a', dependency_map={'a': independent_param}) self._thickness_constraints_setup = True def _enable_thickness_constraints(self): - """ - Enable the thickness constraint. - """ + """Enable the thickness constraint.""" if self._thickness_constraints_setup: # Make sure that the thickness constraint is enabled self._setup_thickness_constraints() @@ -103,9 +110,7 @@ def _enable_thickness_constraints(self): raise Exception('Thickness constraints not setup') def _disable_thickness_constraints(self): - """ - Disable the thickness constraint. - """ + """Disable the thickness constraint.""" if self._thickness_constraints_setup: for i in range(1, len(self.layers)): self.layers[i].thickness.make_independent() @@ -113,25 +118,19 @@ def _disable_thickness_constraints(self): raise Exception('Thickness constraints not setup') def _setup_roughness_constraints(self) -> None: - """ - Setup roughness constraint, front layer is the deciding layer - """ + """Setup roughness constraint, front layer is the deciding layer.""" independent_parameter = self.front_layer.roughness for i in range(1, len(self.layers)): self.layers[i].roughness.make_dependent_on(dependency_expression='a', dependency_map={'a': independent_parameter}) self._roughness_constraints_setup = True def _enable_roughness_constraints(self): - """ - Enable the roughness constraint. - """ + """Enable the roughness constraint.""" independent_parameter = self.front_layer.roughness for i in range(1, len(self.layers)): self.layers[i].roughness.make_dependent_on(dependency_expression='a', dependency_map={'a': independent_parameter}) def _disable_roughness_constraints(self): - """ - Disable the roughness constraint. - """ + """Disable the roughness constraint.""" for i in range(1, len(self.layers)): self.layers[i].roughness.make_independent() diff --git a/src/easyreflectometry/sample/assemblies/bilayer.py b/src/easyreflectometry/sample/assemblies/bilayer.py index 21c428f6..5409d359 100644 --- a/src/easyreflectometry/sample/assemblies/bilayer.py +++ b/src/easyreflectometry/sample/assemblies/bilayer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import Any @@ -64,19 +67,29 @@ def __init__( ): """Constructor. - :param front_head_layer: Layer representing the front head part of the bilayer. - :param front_tail_layer: Layer representing the front tail part of the bilayer. + Parameters + ---------- + front_head_layer : LayerAreaPerMolecule | None, optional + Layer representing the front head part of the bilayer. By default, None. + front_tail_layer : LayerAreaPerMolecule | None, optional + Layer representing the front tail part of the bilayer. A back tail layer is created internally with its thickness, area per molecule, - and solvent fraction constrained to match this layer. - :param back_head_layer: Layer representing the back head part of the bilayer. - :param name: Name for bilayer, defaults to 'EasyBilayer'. - :param unique_name: Unique name for internal object tracking, defaults to `None`. - :param constrain_heads: When `True`, the back head layer thickness and area per + and solvent fraction constrained to match this layer. By default, None. + back_head_layer : LayerAreaPerMolecule | None, optional + Layer representing the back head part of the bilayer. By default, None. + name : str, optional + Name for bilayer. By default, 'EasyBilayer'. + unique_name : str | None, optional + Unique name for internal object tracking. By default, None. + constrain_heads : bool, optional + When `True`, the back head layer thickness and area per molecule are constrained to match the front head layer. Solvent fraction - (hydration) remains independent on each side. Defaults to `True`. - :param conformal_roughness: When `True`, all four layer interfaces share - the same roughness value, controlled by the front head layer. Defaults to `True`. - :param interface: Calculator interface, defaults to `None`. + (hydration) remains independent on each side. By default, True. + conformal_roughness : bool, optional + When `True`, all four layer interfaces share + the same roughness value, controlled by the front head layer. By default, True. + interface : Any, optional + Calculator interface. By default, None. """ # Generate unique name for nested objects if unique_name is None: @@ -154,10 +167,19 @@ def _create_default_head_layer( ) -> LayerAreaPerMolecule: """Create a default head layer with DPPC head group parameters. - :param unique_name: Base unique name for internal object tracking. - :param name_suffix: Suffix for layer name ('Front' or 'Back'). - :param interface: Calculator interface, defaults to `None`. - :return: A new LayerAreaPerMolecule for the head group. + Parameters + ---------- + unique_name : str + Base unique name for internal object tracking. + name_suffix : str + Suffix for layer name ('Front' or 'Back'). + interface : Any, optional + Calculator interface. By default, None. + + Returns + ------- + LayerAreaPerMolecule + A new LayerAreaPerMolecule for the head group. """ solvent = Material( sld=DEFAULTS['solvent']['sld'], @@ -185,9 +207,17 @@ def _create_default_tail_layer( ) -> LayerAreaPerMolecule: """Create a default tail layer with DPPC tail group parameters. - :param unique_name: Base unique name for internal object tracking. - :param interface: Calculator interface, defaults to `None`. - :return: A new LayerAreaPerMolecule for the tail group. + Parameters + ---------- + unique_name : str + Base unique name for internal object tracking. + interface : Any, optional + Calculator interface. By default, None. + + Returns + ------- + LayerAreaPerMolecule + A new LayerAreaPerMolecule for the tail group. """ solvent = Material( sld=DEFAULTS['solvent']['sld'], @@ -216,10 +246,19 @@ def _create_back_tail_layer( ) -> LayerAreaPerMolecule: """Create a back tail layer with initial values copied from the front tail layer. - :param front_tail_layer: The front tail layer to copy initial values from. - :param unique_name: Base unique name for internal object tracking. - :param interface: Calculator interface, defaults to `None`. - :return: A new LayerAreaPerMolecule for the back tail. + Parameters + ---------- + front_tail_layer : LayerAreaPerMolecule + The front tail layer to copy initial values from. + unique_name : str + Base unique name for internal object tracking. + interface : Any, optional + Calculator interface. By default, None. + + Returns + ------- + LayerAreaPerMolecule + A new LayerAreaPerMolecule for the back tail. """ solvent = Material( sld=DEFAULTS['solvent']['sld'], @@ -312,7 +351,10 @@ def constrain_heads(self, status: bool) -> None: are constrained to match the front head layer. Solvent fraction (hydration) remains independent. - :param status: Boolean for the constraint status. + Parameters + ---------- + status : bool + Boolean for the constraint status. """ if status: self._enable_head_constraints() @@ -354,7 +396,10 @@ def conformal_roughness(self, status: bool) -> None: When enabled, all layers share the same roughness parameter (controlled by the front head layer). - :param status: Boolean for the constraint status. + Parameters + ---------- + status : bool + Boolean for the constraint status. """ if status: self._setup_roughness_constraints() @@ -367,7 +412,10 @@ def conformal_roughness(self, status: bool) -> None: def constrain_solvent_roughness(self, solvent_roughness: Parameter) -> None: """Add the constraint to the solvent roughness. - :param solvent_roughness: The solvent roughness parameter. + Parameters + ---------- + solvent_roughness : Parameter + The solvent roughness parameter. """ if not self.conformal_roughness: raise ValueError('Roughness must be conformal to use this function.') @@ -395,16 +443,28 @@ def constrain_multiple_contrast( Makes this bilayer's parameters dependent on another_contrast's parameters, so that changes to another_contrast propagate to this bilayer. - :param another_contrast: The bilayer to constrain to. - :param front_head_thickness: Constrain front head thickness. - :param back_head_thickness: Constrain back head thickness. - :param tail_thickness: Constrain tail thickness. - :param front_head_area_per_molecule: Constrain front head area per molecule. - :param back_head_area_per_molecule: Constrain back head area per molecule. - :param tail_area_per_molecule: Constrain tail area per molecule. - :param front_head_fraction: Constrain front head solvent fraction. - :param back_head_fraction: Constrain back head solvent fraction. - :param tail_fraction: Constrain tail solvent fraction. + Parameters + ---------- + another_contrast : Bilayer + The bilayer to constrain to. + front_head_thickness : bool, optional + Constrain front head thickness. By default, True. + back_head_thickness : bool, optional + Constrain back head thickness. By default, True. + tail_thickness : bool, optional + Constrain tail thickness. By default, True. + front_head_area_per_molecule : bool, optional + Constrain front head area per molecule. By default, True. + back_head_area_per_molecule : bool, optional + Constrain back head area per molecule. By default, True. + tail_area_per_molecule : bool, optional + Constrain tail area per molecule. By default, True. + front_head_fraction : bool, optional + Constrain front head solvent fraction. By default, True. + back_head_fraction : bool, optional + Constrain back head solvent fraction. By default, True. + tail_fraction : bool, optional + Constrain tail solvent fraction. By default, True. """ if front_head_thickness: self.front_head_layer.thickness.make_dependent_on( @@ -479,7 +539,10 @@ def as_dict(self, skip: list[str] | None = None) -> dict: The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : list[str] | None, optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['front_head_layer'] = self.front_head_layer.as_dict(skip=skip) diff --git a/src/easyreflectometry/sample/assemblies/gradient_layer.py b/src/easyreflectometry/sample/assemblies/gradient_layer.py index 38771e80..1e08bb2e 100644 --- a/src/easyreflectometry/sample/assemblies/gradient_layer.py +++ b/src/easyreflectometry/sample/assemblies/gradient_layer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from easyscience import global_object @@ -11,8 +14,8 @@ class GradientLayer(BaseAssembly): """A set of discrete gradient layers changing from the front to the back material. - The front layer is where the neutron beam starts in, it has an index of 0. + The front layer is where the neutron beam starts in, it has an index of 0. """ def __init__( @@ -28,13 +31,24 @@ def __init__( ): """Constructor. - :param front_material: Material of front of the layer - :param back_material: Material of back of the layer - :param thickness: Thicknkess of the layer - :param roughness: Roughness of the layer - :param discretisation_elements: Number of discrete layers - :param name: Name for gradient layer, defaults to 'EasyGradienLayer'. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + front_material : Optional[Material], optional + Material of front of the layer. By default, None. + back_material : Optional[Material], optional + Material of back of the layer. By default, None. + thickness : Optional[float], optional + Thicknkess of the layer. By default, 2.0. + roughness : Optional[float], optional + Roughness of the layer. By default, 0.2. + discretisation_elements : int, optional + Number of discrete layers. By default, 10. + name : str, optional + Name for gradient layer. By default, 'EasyGradienLayer'. + interface : + Calculator interface. By default, None. """ if front_material is None: @@ -82,7 +96,10 @@ def thickness(self) -> float: def thickness(self, thickness: float) -> None: """Set the thickness of the gradient layer. - :param thickness: Thickness of the gradient layer in Angstroms. + Parameters + ---------- + thickness : float + Thickness of the gradient layer in Angstroms. """ self.front_layer.thickness.value = thickness / self._discretisation_elements @@ -95,7 +112,10 @@ def roughness(self) -> float: def roughness(self, roughness: float) -> None: """Set the roughness of the gradient layer. - :param roughness: Roughness of the gradient layer in Angstroms. + Parameters + ---------- + roughness : float + Roughness of the gradient layer in Angstroms. """ self.front_layer.roughness.value = roughness @@ -103,7 +123,7 @@ def roughness(self, roughness: float) -> None: def _dict_repr(self) -> dict[str, str]: """A simplified dict representation.""" return { - 'thickness': float(self.thickness), # Conversion to float is necessary to prevent property reference in dict + 'thickness': float(self.thickness), # Conversion to float is necessary to prevent property reference in dict 'discretisation_elements': int(self._discretisation_elements), # Same as above 'back_layer': self.back_layer._dict_repr, 'front_layer': self.front_layer._dict_repr, @@ -111,9 +131,13 @@ def _dict_repr(self) -> dict[str, str]: def as_dict(self, skip: Optional[list[str]] = None) -> dict: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) # Determined in __init__ @@ -126,6 +150,7 @@ def _linear_gradient( back_value: float, discretisation_elements: int, ) -> list[float]: + """Linear gradient.""" discrete_step = (back_value - front_value) / discretisation_elements if discrete_step != 0: # Both front and back values are included @@ -141,6 +166,7 @@ def _prepare_gradient_layers( discretisation_elements: int, interface=None, ) -> LayerCollection: + """Prepare gradient layers.""" gradient_sld = _linear_gradient( front_value=front_material.sld.value, back_value=back_material.sld.value, diff --git a/src/easyreflectometry/sample/assemblies/multilayer.py b/src/easyreflectometry/sample/assemblies/multilayer.py index 360db10a..9144b3a8 100644 --- a/src/easyreflectometry/sample/assemblies/multilayer.py +++ b/src/easyreflectometry/sample/assemblies/multilayer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import Optional @@ -10,6 +13,7 @@ class Multilayer(BaseAssembly): """A multi layer is build from a single or a list of `Layer` or `LayerCollection`. + The multi layer will arrange the layers as slabs, allowing the reflectometry to be determined from them. The front layer is where the neutron beam starts in, it has an index of 0. @@ -30,10 +34,20 @@ def __init__( ): """Constructor. - :param layers: The layers that make up the multi-layer. - :param name: Name for multi layer, defaults to 'EasyMultilayer'. - :param interface: Calculator interface, defaults to `None`. - :param type: Type of the constructed instance, defaults to 'Multi-layer' + Parameters + ---------- + populate_if_none : Optional[bool], optional + By default, True. + unique_name : Optional[str], optional + By default, None. + layers : Union[Layer, list[Layer], LayerCollection, None], optional + The layers that make up the multi-layer. By default, None. + name : str, optional + Name for multi layer. By default, 'EasyMultilayer'. + interface : + Calculator interface. By default, None. + type : str, optional + Type of the constructed instance. By default, 'Multi-layer'. """ if layers is None: if populate_if_none: @@ -53,7 +67,10 @@ def __init__( def add_layer(self, *layers: tuple[Layer]) -> None: """Add a layer to the multi layer. - :param layers: Layers to add to the multi layer. + Parameters + ---------- + *layers : tuple[Layer] + Layers to add to the multi layer. """ for arg in layers: if issubclass(arg.__class__, Layer): @@ -64,8 +81,10 @@ def add_layer(self, *layers: tuple[Layer]) -> None: def duplicate_layer(self, idx: int) -> None: """Duplicate a given layer. - :param idx: index of layer to duplicate. - :type idx: int + Parameters + ---------- + idx : int + Index of layer to duplicate. """ to_duplicate = self.layers[idx] duplicate_layer = Layer( @@ -79,7 +98,10 @@ def duplicate_layer(self, idx: int) -> None: def remove_layer(self, idx: int) -> None: """Remove a layer from the item. - :param idx: index of layer to remove + Parameters + ---------- + idx : int + Index of layer to remove. """ if self.interface is not None: self.interface().remove_layer_from_item(self.layers[idx].unique_name, self.unique_name) @@ -93,11 +115,6 @@ def _dict_repr(self) -> dict: @classmethod def from_dict(cls, data: dict) -> Multilayer: - """ - Create a Multilayer from a dictionary. - - :param data: dictionary of the Multilayer - :return: Multilayer - """ + """Create a Multilayer from a dictionary.""" multilayer = super().from_dict(data) return multilayer diff --git a/src/easyreflectometry/sample/assemblies/repeating_multilayer.py b/src/easyreflectometry/sample/assemblies/repeating_multilayer.py index 7c4ecbcc..cb396836 100644 --- a/src/easyreflectometry/sample/assemblies/repeating_multilayer.py +++ b/src/easyreflectometry/sample/assemblies/repeating_multilayer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -22,8 +25,7 @@ class RepeatingMultilayer(Multilayer): - """ - A repeating multi layer is build from a `Multilayer` and which it repeats + """A repeating multi layer is build from a `Multilayer` and which it repeats for a given number of times. This enables a computational efficiency in many reflectometry engines as the operation can be performed for a single `Multilayer` and cheaply combined for the appropriate number of @@ -46,10 +48,20 @@ def __init__( ): """Constructor. - :param layers: The layers that make up the multi-layer that will be repeated. - :param repetitions: Number of repetitions of the given series of layers - :param name: Name for the repeating multi layer, defaults to 'EasyRepeatingMultilayer'. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + populate_if_none : bool, optional + By default, True. + unique_name : Optional[str], optional + By default, None. + layers : Union[LayerCollection, Layer, list[Layer], None], optional + The layers that make up the multi-layer that will be repeated. By default, None. + repetitions : Union[Parameter, int, None], optional + Number of repetitions of the given series of layers. By default, None. + name : str, optional + Name for the repeating multi layer. By default, 'EasyRepeatingMultilayer'. + interface : + Calculator interface. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) diff --git a/src/easyreflectometry/sample/assemblies/surfactant_layer.py b/src/easyreflectometry/sample/assemblies/surfactant_layer.py index 6cbd2c6b..81c9c36c 100644 --- a/src/easyreflectometry/sample/assemblies/surfactant_layer.py +++ b/src/easyreflectometry/sample/assemblies/surfactant_layer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import Optional @@ -37,12 +40,22 @@ def __init__( ): """Constructor. - :param tail_layer: Layer representing the tail part of the surfactant layer. - :param head_layer: Layer representing the head part of the surfactant layer. - :param name: Name for surfactant layer, defaults to 'EasySurfactantLayer'. - :param constrain_area_per_molecule: Constrain the area per molecule, defaults to `False`. - :param conformal_roughness: Constrain the roughness to be the same for both layers, defaults to `False`. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + tail_layer : Optional[LayerAreaPerMolecule], optional + Layer representing the tail part of the surfactant layer. By default, None. + head_layer : Optional[LayerAreaPerMolecule], optional + Layer representing the head part of the surfactant layer. By default, None. + name : str, optional + Name for surfactant layer. By default, 'EasySurfactantLayer'. + constrain_area_per_molecule : bool, optional + Constrain the area per molecule. By default, False. + conformal_roughness : bool, optional + Constrain the roughness to be the same for both layers. By default, False. + interface : + Calculator interface. By default, None. """ # We need to generate a unique name to create the nested objects if unique_name is None: @@ -138,7 +151,10 @@ def constrain_area_per_molecule(self, status: bool): """Set the status for the area per molecule constraint such that the head and tail layers have the same area per molecule. - :param status: Boolean description the wanted of the constraint. + Parameters + ---------- + status : bool + Boolean description the wanted of the constraint. """ if status: independent_param = self.tail_layer._area_per_molecule @@ -158,7 +174,10 @@ def conformal_roughness(self) -> bool: def conformal_roughness(self, status: bool): """Set the status for the roughness to be the same for both layers. - :param status: Boolean description the wanted of the constraint. + Parameters + ---------- + status : bool + Boolean description the wanted of the constraint. """ if status: self._enable_roughness_constraints() @@ -170,7 +189,10 @@ def conformal_roughness(self, status: bool): def constrain_solvent_roughness(self, solvent_roughness: Parameter): """Add the constraint to the solvent roughness. - :param solvent_roughness: The solvent roughness parameter. + Parameters + ---------- + solvent_roughness : Parameter + The solvent roughness parameter. """ if not self.conformal_roughness: raise ValueError('Roughness must be conformal to use this function.') @@ -189,7 +211,22 @@ def constrain_multiple_contrast( ): """Constrain structural parameters between surfactant layer objects. - :param another_contrast: The surfactant layer to constrain + Parameters + ---------- + tail_layer_fraction : bool, optional + By default, True. + head_layer_fraction : bool, optional + By default, True. + tail_layer_area_per_molecule : bool, optional + By default, True. + head_layer_area_per_molecule : bool, optional + By default, True. + tail_layer_thickness : bool, optional + By default, True. + head_layer_thickness : bool, optional + By default, True. + another_contrast : SurfactantLayer + The surfactant layer to constrain. """ if head_layer_thickness: self.head_layer.thickness.make_dependent_on( @@ -241,9 +278,13 @@ def _dict_repr(self) -> dict: def as_dict(self, skip: Optional[list[str]] = None) -> dict: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['tail_layer'] = self.tail_layer.as_dict(skip=skip) diff --git a/src/easyreflectometry/sample/base_core.py b/src/easyreflectometry/sample/base_core.py index b4c3f3ed..4cf600a6 100644 --- a/src/easyreflectometry/sample/base_core.py +++ b/src/easyreflectometry/sample/base_core.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from abc import abstractmethod from easyscience import ObjBase as BaseObj @@ -12,6 +15,7 @@ def __init__( interface, **kwargs, ): + """Init function.""" super().__init__(name=name, **kwargs) # Updates interface using property in base object @@ -21,11 +25,12 @@ def __init__( def _dict_repr(self) -> dict[str, str]: ... def __repr__(self) -> str: - """ - String representation of the layer. + """String representation of the layer. - :return: a string representation of the layer - :rtype: str + Returns + ------- + str + A string representation of the layer. """ return yaml_dump(self._dict_repr) diff --git a/src/easyreflectometry/sample/collections/__init__.py b/src/easyreflectometry/sample/collections/__init__.py new file mode 100644 index 00000000..4e798e20 --- /dev/null +++ b/src/easyreflectometry/sample/collections/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyreflectometry/sample/collections/base_collection.py b/src/easyreflectometry/sample/collections/base_collection.py index 53d16b51..28d494a5 100644 --- a/src/easyreflectometry/sample/collections/base_collection.py +++ b/src/easyreflectometry/sample/collections/base_collection.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import List from typing import Optional @@ -16,6 +19,7 @@ def __init__( unique_name: Optional[str] = None, **kwargs, ): + """Init function.""" if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -27,24 +31,33 @@ def __init__( self.populate_if_none = False def __repr__(self) -> str: - """ - String representation of the collection. + """String representation of the collection. - :return: a string representation of the collection + Returns + ------- + str + A string representation of the collection. """ return yaml_dump(self._dict_repr) @property def names(self) -> list: - """ - :returns: list of names for the elements in the collection. + """Names function. + + Returns + ------- + s : list + List of names for the elements in the collection. """ return [i.name for i in self] def move_up(self, index: int): """Move the element at the given index up in the collection. - :param index: Index of the element to move up. + Parameters + ---------- + index : int + Index of the element to move up. """ if index == 0: return @@ -53,34 +66,43 @@ def move_up(self, index: int): def move_down(self, index: int): """Move the element at the given index down in the collection. - :param index: Index of the element to move down. + Parameters + ---------- + index : int + Index of the element to move down. """ if index == len(self) - 1: return self.insert(index + 1, self.pop(index)) def remove(self, index: int): - """ - Remove an element from the elements. + """Remove an element from the elements. - :param index: Index of the element to remove + Parameters + ---------- + index : int + Index of the element to remove. """ self.pop(index) @property def _dict_repr(self) -> dict: - """ - A simplified dict representation. + """A simplified dict representation. - :return: Simple dictionary + Returns + ------- + dict + Simple dictionary. """ return {self.name: [i._dict_repr for i in self]} def as_dict(self, skip: Optional[List[str]] = None) -> dict: - """ - Create a dictionary representation of the collection. + """Create a dictionary representation of the collection. - :return: A dictionary representation of the collection + Returns + ------- + dict + A dictionary representation of the collection. """ if skip is None: skip = [] @@ -92,4 +114,5 @@ def as_dict(self, skip: Optional[List[str]] = None) -> dict: return this_dict def __deepcopy__(self, memo): + """Deepcopy function.""" return self.from_dict(self.as_dict(skip=['unique_name'])) diff --git a/src/easyreflectometry/sample/collections/layer_collection.py b/src/easyreflectometry/sample/collections/layer_collection.py index 0761f861..99424f72 100644 --- a/src/easyreflectometry/sample/collections/layer_collection.py +++ b/src/easyreflectometry/sample/collections/layer_collection.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional @@ -16,6 +18,7 @@ def __init__( populate_if_none: bool = True, # Needed to match as_dict signature from BaseCollection **kwargs, ): + """Init function.""" if not layers: layers = [] @@ -24,7 +27,10 @@ def __init__( def add_layer(self, layer: Optional[Layer] = None): """Add a layer to the collection. - :param layer: Layer to add. + Parameters + ---------- + layer : Optional[Layer], optional + Layer to add. By default, None. """ if layer is None: layer = Layer( @@ -36,7 +42,11 @@ def add_layer(self, layer: Optional[Layer] = None): def duplicate_layer(self, index: int): """Duplicate a layer in the collection. - :param layer: Assembly to add. + Parameters + ---------- + index : int + layer : + Assembly to add. """ to_be_duplicated = self[index] duplicate = Layer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) diff --git a/src/easyreflectometry/sample/collections/material_collection.py b/src/easyreflectometry/sample/collections/material_collection.py index a97f89d9..d7b5af3b 100644 --- a/src/easyreflectometry/sample/collections/material_collection.py +++ b/src/easyreflectometry/sample/collections/material_collection.py @@ -1,4 +1,7 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + + from typing import Optional from typing import Tuple @@ -8,6 +11,7 @@ # Needs to be a function, elements are added to the global_object.map def DEFAULT_ELEMENTS(interface): + """Default elements.""" return ( Material(sld=0.0, isld=0.0, name='Air', interface=interface), Material(sld=6.335, isld=0.0, name='D2O', interface=interface), @@ -25,6 +29,7 @@ def __init__( populate_if_none: bool = True, **kwargs, ): + """Init function.""" if not materials: # Empty tuple if no materials are provided if populate_if_none: materials = DEFAULT_ELEMENTS(interface) @@ -42,7 +47,10 @@ def __init__( def add_material(self, material: Optional[Material] = None): """Add a material to the collection. - :param material: Material to add. + Parameters + ---------- + material : Optional[Material], optional + Material to add. By default, None. """ if material is None: material = Material(sld=0.0, isld=0.0, name='Material added') @@ -52,7 +60,11 @@ def add_material(self, material: Optional[Material] = None): def duplicate_material(self, index: int): """Duplicate a material in the collection. - :param material: Assembly to add. + Parameters + ---------- + index : int + material : + Assembly to add. """ to_be_duplicated = self[index] duplicate = Material.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) diff --git a/src/easyreflectometry/sample/collections/sample.py b/src/easyreflectometry/sample/collections/sample.py index 65c2a76b..1bbdb156 100644 --- a/src/easyreflectometry/sample/collections/sample.py +++ b/src/easyreflectometry/sample/collections/sample.py @@ -1,6 +1,7 @@ -from __future__ import annotations +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause -__author__ = 'github.com/arm61' +from __future__ import annotations from typing import List from typing import Optional @@ -15,7 +16,7 @@ # Needs to be a function, elements are added to the global_object.map def DEFAULT_ELEMENTS(interface): - """:meta private:""" + """:meta private:.""" return ( Multilayer(interface=interface), Multilayer(interface=interface), @@ -36,9 +37,20 @@ def __init__( ): """Constructor. - :param args: The assemblies in the sample. - :param name: Name of the sample, defaults to 'EasySample'. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + **kwargs : + populate_if_none : bool, optional + By default, True. + unique_name : Optional[str], optional + By default, None. + *assemblies : Optional[List[BaseAssembly]] + args : + The assemblies in the sample. + name : str, optional + Name of the sample. By default, 'EasySample'. + interface : + Calculator interface. By default, None. """ if not assemblies: if populate_if_none: @@ -54,7 +66,10 @@ def __init__( def add_assembly(self, assembly: Optional[BaseAssembly] = None): """Add an assembly to the sample. - :param assembly: Assembly to add. + Parameters + ---------- + assembly : Optional[BaseAssembly], optional + Assembly to add. By default, None. """ if assembly is None: assembly = Multilayer( @@ -66,7 +81,11 @@ def add_assembly(self, assembly: Optional[BaseAssembly] = None): def duplicate_assembly(self, index: int): """Add an assembly to the sample. - :param assembly: Assembly to add. + Parameters + ---------- + index : int + assembly : + Assembly to add. """ to_be_duplicated = self[index] if isinstance(to_be_duplicated, Multilayer): @@ -81,21 +100,30 @@ def duplicate_assembly(self, index: int): def move_up(self, index: int): """Move the assembly at the given index up in the sample. - :param index: Index of the assembly to move up. + Parameters + ---------- + index : int + Index of the assembly to move up. """ super().move_up(index) def move_down(self, index: int): """Move the assembly at the given index down in the sample. - :param index: Index of the assembly to move down. + Parameters + ---------- + index : int + Index of the assembly to move down. """ super().move_down(index) def remove_assembly(self, index: int): """Remove the assembly at the given index from the sample. - :param index: Index of the assembly to remove. + Parameters + ---------- + index : int + Index of the assembly to remove. """ self.pop(index) @@ -116,9 +144,13 @@ def subphase(self) -> Layer: # Representation def as_dict(self, skip: Optional[List[str]] = None) -> dict: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[List[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['populate_if_none'] = self.populate_if_none diff --git a/src/easyreflectometry/sample/elements/__init__.py b/src/easyreflectometry/sample/elements/__init__.py new file mode 100644 index 00000000..4e798e20 --- /dev/null +++ b/src/easyreflectometry/sample/elements/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyreflectometry/sample/elements/layers/__init__.py b/src/easyreflectometry/sample/elements/layers/__init__.py new file mode 100644 index 00000000..4e798e20 --- /dev/null +++ b/src/easyreflectometry/sample/elements/layers/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyreflectometry/sample/elements/layers/layer.py b/src/easyreflectometry/sample/elements/layers/layer.py index 513b18f9..fa58dc15 100644 --- a/src/easyreflectometry/sample/elements/layers/layer.py +++ b/src/easyreflectometry/sample/elements/layers/layer.py @@ -1,4 +1,7 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + + from typing import Optional from typing import Union @@ -53,11 +56,20 @@ def __init__( ): """Constructor. - :param material: The material for the layer. - :param thickness: Layer thickness in Angstrom. - :param roughness: Upper roughness on the layer in Angstrom. - :param name: Name of the layer, defaults to 'EasyLayer' - :param interface: Interface object, defaults to `None` + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + material : Union[Material, None], optional + The material for the layer. By default, None. + thickness : Union[Parameter, float, None], optional + Layer thickness in Angstrom. By default, None. + roughness : Union[Parameter, float, None], optional + Upper roughness on the layer in Angstrom. By default, None. + name : str, optional + Name of the layer. By default, 'EasyLayer'. + interface : + Interface object. By default, None. """ if material is None: material = Material(interface=interface) @@ -95,7 +107,10 @@ def __init__( def assign_material(self, material: Material) -> None: """Assign a material to the layer interface. - :param material: The material to assign to the layer. + Parameters + ---------- + material : Material + The material to assign to the layer. """ self.material = material if self.interface is not None: diff --git a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py index dbda1473..9053aa95 100644 --- a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +++ b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -50,7 +53,6 @@ class LayerAreaPerMolecule(Layer): """The `LayerAreaPerMolecule` class allows a layer to be defined in terms of some molecular formula an area per molecule, and a solvent. - """ # Added in __init__ @@ -78,14 +80,26 @@ def __init__( ): """Constructor. - :param molecular_formula: Formula for the molecule in the layer. - :param thickness: Layer thickness in Angstrom. - :param solvent: Solvent containing the molecule. - :param solvent_fraction: Fraction of solvent in layer. Fx solvation or surface coverage. - :param area_per_molecule: Area per molecule in the layer - :param roughness: Upper roughness on the layer in Angstrom. - :param name: Name of the layer, defaults to "EasyLayerAreaPerMolecule" - :param interface: Interface object, defaults to `None` + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + molecular_formula : Union[str, None], optional + Formula for the molecule in the layer. By default, None. + thickness : Union[Parameter, float, None], optional + Layer thickness in Angstrom. By default, None. + solvent : Union[Material, None], optional + Solvent containing the molecule. By default, None. + solvent_fraction : Union[Parameter, float, None], optional + Fraction of solvent in layer. Fx solvation or surface coverage. By default, None. + area_per_molecule : Union[Parameter, float, None], optional + Area per molecule in the layer. By default, None. + roughness : Union[Parameter, float, None], optional + Upper roughness on the layer in Angstrom. By default, None. + name : str, optional + Name of the layer. By default, 'EasyLayerAreaPerMolecule'. + interface : + Interface object. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -190,7 +204,10 @@ def area_per_molecule(self) -> float: def area_per_molecule(self, new_area_per_molecule: float) -> None: """Set the area per molecule. - :param new_area_per_molecule: New area per molecule. + Parameters + ---------- + new_area_per_molecule : float + New area per molecule. """ if new_area_per_molecule < 0: raise ValueError('new_area_per_molecule must be greater than 0.0.') @@ -210,7 +227,10 @@ def solvent(self) -> Material: def solvent(self, new_solvent: Material) -> None: """Set the solvent material. - :param new_solvent: New solvent material. + Parameters + ---------- + new_solvent : Material + New solvent material. """ self.material.solvent = new_solvent @@ -222,6 +242,7 @@ def solvent_fraction_parameter(self) -> float: @property def solvent_fraction(self) -> float: """Get the fraction of the layer occupied by the solvent. + This could be a result of either water solvating the molecule, or incomplete surface coverage of the molecules. """ return self.material.solvent_fraction @@ -229,9 +250,13 @@ def solvent_fraction(self) -> float: @solvent_fraction.setter def solvent_fraction(self, solvent_fraction: float) -> None: """Set the fraction of the layer occupied by the solvent. + This could be a result of either water solvating the molecule, or incomplete surface coverage of the molecules. - :param solvent_fraction: Fraction of layer described by the solvent. + Parameters + ---------- + solvent_fraction : float + Fraction of layer described by the solvent. """ self.material.solvent_fraction = solvent_fraction @@ -244,7 +269,10 @@ def molecular_formula(self) -> str: def molecular_formula(self, formula_string: str) -> None: """Set the formula of the molecule in the material. - :param formula_string: String that defines the molecular formula. + Parameters + ---------- + formula_string : str + String that defines the molecular formula. """ self._molecular_formula = formula_string scattering_length = neutron_scattering_length(formula_string) @@ -257,7 +285,10 @@ def molecular_formula(self, formula_string: str) -> None: @property def _dict_repr(self) -> dict[str, str]: - """Dictionary representation of the `area_per_molecule` object. Produces a simple dictionary""" + """Dictionary representation of the `area_per_molecule` object. + + Produces a simple dictionary. + """ dict_repr = super()._dict_repr dict_repr['molecular_formula'] = self._molecular_formula dict_repr['area_per_molecule'] = f'{self.area_per_molecule:.2f} {self._area_per_molecule.unit}' @@ -265,9 +296,13 @@ def _dict_repr(self) -> dict[str, str]: def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['solvent_fraction'] = self.material._fraction.as_dict(skip=skip) diff --git a/src/easyreflectometry/sample/elements/materials/__init__.py b/src/easyreflectometry/sample/elements/materials/__init__.py new file mode 100644 index 00000000..4e798e20 --- /dev/null +++ b/src/easyreflectometry/sample/elements/materials/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyreflectometry/sample/elements/materials/material.py b/src/easyreflectometry/sample/elements/materials/material.py index 8c030031..42091bd6 100644 --- a/src/easyreflectometry/sample/elements/materials/material.py +++ b/src/easyreflectometry/sample/elements/materials/material.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -49,10 +51,18 @@ def __init__( ): """Constructor. - :param sld: Real scattering length density. - :param isld: Imaginary scattering length density. - :param name: Name of the material, defaults to 'EasyMaterial'. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + sld : Union[Parameter, float, None], optional + Real scattering length density. By default, None. + isld : Union[Parameter, float, None], optional + Imaginary scattering length density. By default, None. + name : str, optional + Name of the material. By default, 'EasyMaterial'. + interface : + Calculator interface. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) diff --git a/src/easyreflectometry/sample/elements/materials/material_density.py b/src/easyreflectometry/sample/elements/materials/material_density.py index 85a3bf1b..b85bda98 100644 --- a/src/easyreflectometry/sample/elements/materials/material_density.py +++ b/src/easyreflectometry/sample/elements/materials/material_density.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -54,10 +57,18 @@ def __init__( ): """Constructor. - :param chemical_structure: Chemical formula for the material. - :param density: Mass density for the material. - :param name: Identifier, defaults to `EasyMaterialDensity`. - :param interface: Interface object, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + chemical_structure : Union[str, None], optional + Chemical formula for the material. By default, None. + density : Union[Parameter, float, None], optional + Mass density for the material. By default, None. + name : str, optional + Identifier. By default, 'EasyMaterialDensity'. + interface : + Interface object. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -130,7 +141,10 @@ def chemical_structure(self) -> str: def chemical_structure(self, structure_string: str) -> None: """Set the chemical structure string. - :param structure_string: String that defines the chemical structure. + Parameters + ---------- + structure_string : str + String that defines the chemical structure. """ self._chemical_structure = structure_string scattering_length = neutron_scattering_length(structure_string) @@ -147,9 +161,13 @@ def _dict_repr(self) -> dict[str, str]: def as_dict(self, skip: list = []) -> dict[str, str]: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : list, optional + List of keys to skip. By default, []. """ this_dict = super().as_dict(skip=skip) # From Material diff --git a/src/easyreflectometry/sample/elements/materials/material_mixture.py b/src/easyreflectometry/sample/elements/materials/material_mixture.py index a54f3d9d..c999093e 100644 --- a/src/easyreflectometry/sample/elements/materials/material_mixture.py +++ b/src/easyreflectometry/sample/elements/materials/material_mixture.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -41,11 +44,20 @@ def __init__( ): """Constructor. - :param material_a: The first material. - :param material_b: The second material. - :param fraction: The fraction of material_b in material_a. - :param name: Name of the material, defaults to None that causes the name to be constructed. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + material_a : Union[Material, None], optional + The first material. By default, None. + material_b : Union[Material, None], optional + The second material. By default, None. + fraction : Union[Parameter, float, None], optional + The fraction of material_b in material_a. By default, None. + name : Union[str, None], optional + Name of the material. By default, None. + interface : + Calculator interface. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -102,22 +114,34 @@ def __init__( self.interface = interface def _get_linkable_attributes(self): + """Get linkable attributes.""" return [self._sld, self._isld] @property def sld(self) -> float: + """Sld function.""" return self._sld.value @property def isld(self) -> float: + """Isld function.""" return self._isld.value def _materials_constraints(self): + """Materials constraints.""" dependency_expression = 'a * (1 - p) + b * p' - dependency_map = {'a': self._material_a.sld, 'b': self._material_b.sld, 'p': self._fraction} + dependency_map = { + 'a': self._material_a.sld, + 'b': self._material_b.sld, + 'p': self._fraction, + } self._sld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) - dependency_map = {'a': self._material_a.isld, 'b': self._material_b.isld, 'p': self._fraction} + dependency_map = { + 'a': self._material_a.isld, + 'b': self._material_b.isld, + 'p': self._fraction, + } self._isld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) @property @@ -129,7 +153,10 @@ def fraction(self) -> float: def fraction(self, fraction: float) -> None: """Setter for fraction of material_b. - :param fraction: The fraction of material_b in material_a. + Parameters + ---------- + fraction : float + The fraction of material_b in material_a. """ if not isinstance(fraction, float): raise ValueError('fraction must be a float') @@ -142,9 +169,12 @@ def material_a(self) -> Material: @material_a.setter def material_a(self, new_material_a: Material) -> None: - """Setter for material_a + """Setter for material_a. - :param new_material_a: New Material for material_a + Parameters + ---------- + new_material_a : Material + New Material for material_a. """ self._material_a = new_material_a self._materials_constraints() @@ -159,9 +189,12 @@ def material_b(self) -> Material: @material_b.setter def material_b(self, new_material_b: Material) -> None: - """Setter for material_b + """Setter for material_b. - :param new_material_b: New Materialfor material_b + Parameters + ---------- + new_material_b : Material + New Materialfor material_b. """ self._material_b = new_material_b self._materials_constraints() @@ -170,6 +203,7 @@ def material_b(self, new_material_b: Material) -> None: self._update_name() def _update_name(self) -> None: + """Update name.""" self.name = self._material_a.name + '/' + self._material_b.name # Representation @@ -188,9 +222,13 @@ def _dict_repr(self) -> dict[str, str]: def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['material_a'] = self._material_a.as_dict(skip=skip) diff --git a/src/easyreflectometry/sample/elements/materials/material_solvated.py b/src/easyreflectometry/sample/elements/materials/material_solvated.py index 563e3550..454904ba 100644 --- a/src/easyreflectometry/sample/elements/materials/material_solvated.py +++ b/src/easyreflectometry/sample/elements/materials/material_solvated.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Optional from typing import Union @@ -33,11 +36,20 @@ def __init__( ): """Constructor. - :param material: The material being solvated. - :param solvent: The solvent material. - :param solvent_fraction: Fraction of solvent in layer. E.g. solvation or surface coverage. - :param name: Name of the material, defaults to None that causes the name to be constructed. - :param interface: Calculator interface, defaults to `None`. + Parameters + ---------- + unique_name : Optional[str], optional + By default, None. + material : Union[Material, None], optional + The material being solvated. By default, None. + solvent : Union[Material, None], optional + The solvent material. By default, None. + solvent_fraction : Union[Parameter, float, None], optional + Fraction of solvent in layer. E.g. solvation or surface coverage. By default, None. + name : + Name of the material. By default, None. + interface : + Calculator interface. By default, None. """ if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -74,7 +86,10 @@ def material(self) -> Material: def material(self, new_material: Material) -> None: """Set the material. - :param new_material: Matrerial to be useed. + Parameters + ---------- + new_material : Material + Matrerial to be useed. """ self.material_a = new_material @@ -87,7 +102,10 @@ def solvent(self) -> Material: def solvent(self, new_solvent: Material) -> None: """Set the solvent. - :param new_solvent: Solvent to be used. + Parameters + ---------- + new_solvent : Material + Solvent to be used. """ self.material_b = new_solvent @@ -99,6 +117,7 @@ def solvent_fraction_parameter(self) -> Parameter: @property def solvent_fraction(self) -> float: """Get the fraction of layer described by the solvent. + This might be fraction of: Solvation where solvent is within the layer Patches of solvent in the layer where no material is present. @@ -108,11 +127,15 @@ def solvent_fraction(self) -> float: @solvent_fraction.setter def solvent_fraction(self, solvent_fraction: float) -> None: """Set the fraction of layer covered by the material. + This might be fraction of: Solvation where solvent is within the layer Patches of solvent in the layer where no material is present. - :param solvent_fraction : Fraction of layer described by the solvent. + Parameters + ---------- + solvent_fraction : float + Fraction of layer described by the solvent. """ try: self.fraction = solvent_fraction @@ -122,6 +145,7 @@ def solvent_fraction(self, solvent_fraction: float) -> None: raise ValueError('solvent_fraction must be a float between 0 and 1') def _update_name(self) -> None: + """Update name.""" self.name = self._material_a.name + ' in ' + self._material_b.name # Representation @@ -140,9 +164,13 @@ def _dict_repr(self) -> dict[str, str]: def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: """Produces a cleaned dict using a custom as_dict method to skip necessary things. + The resulting dict matches the parameters in __init__ - :param skip: List of keys to skip, defaults to `None`. + Parameters + ---------- + skip : Optional[list[str]], optional + List of keys to skip. By default, None. """ this_dict = super().as_dict(skip=skip) this_dict['material'] = self.material.as_dict(skip=skip) diff --git a/src/easyreflectometry/special/calculations.py b/src/easyreflectometry/special/calculations.py index f7ea9068..07844d3c 100644 --- a/src/easyreflectometry/special/calculations.py +++ b/src/easyreflectometry/special/calculations.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import periodictable as pt @@ -6,23 +8,37 @@ def weighted_average(a: float, b: float, p: float) -> float: - """ - Determine the weighted average for a and b, where p is the weight. - - :param a: First value - :param b: Second value - :param p: Weight - :return: Weighted average + """Determine the weighted average for a and b, where p is the weight. + + Parameters + ---------- + a : float + First value. + b : float + Second value. + p : float + Weight. + + Returns + ------- + float + Weighted average. """ return a * (1 - p) + b * p def neutron_scattering_length(formula: str) -> complex: - """ - Determine the neutron scattering length for a chemical formula. + """Determine the neutron scattering length for a chemical formula. + + Parameters + ---------- + formula : str + Chemical formula. - :param formula: Chemical formula. - :return: Real and imaginary descriptors for the scattering length in angstrom. + Returns + ------- + complex + Real and imaginary descriptors for the scattering length in angstrom. """ formula_as_dict = parse_formula(formula) scattering_length = 0 + 0j @@ -37,11 +53,17 @@ def neutron_scattering_length(formula: str) -> complex: def molecular_weight(formula: str) -> float: - """ - Determine the molecular weight for a chemical formula. + """Determine the molecular weight for a chemical formula. - :param formula: Chemical formula - :return: Molecular weight of the material in kilograms. + Parameters + ---------- + formula : str + Chemical formula. + + Returns + ------- + float + Molecular weight of the material in kilograms. """ formula_as_dict = parse_formula(formula) mw = 0 @@ -55,25 +77,41 @@ def area_per_molecule_to_scattering_length_density( thickness: float, area_per_molecule: float, ) -> float: - """ - Find the scattering length density for a given area per molecule. - - :param scattering_length: Scattering length of component, in angstrom. - :param thickness: Thickness of component, in angstrom. - :param area_per_molecule: Area per molecule, in angstrom^2. - :return: Scattering length density of layer in e-6 1/angstrom^2. + """Find the scattering length density for a given area per molecule. + + Parameters + ---------- + scattering_length : float + Scattering length of component, in angstrom. + thickness : float + Thickness of component, in angstrom. + area_per_molecule : float + Area per molecule, in angstrom^2. + + Returns + ------- + float + Scattering length density of layer in e-6 1/angstrom^2. """ return scattering_length / (thickness * area_per_molecule) * 1e6 def density_to_sld(scattering_length: float, molecular_weight: float, density: float) -> float: - """ - Find the scattering length density from the mass density of a material. - - :param scattering_length: Scattering length of component, in angstrom. - :param molecular_weight: Molecular weight of component, in u. - :param density: Mass density of the component, in gram centimeter^-3. - :return: Scattering length density of layer in e-6 1/angstrom^2. + """Find the scattering length density from the mass density of a material. + + Parameters + ---------- + scattering_length : float + Scattering length of component, in angstrom. + molecular_weight : float + Molecular weight of component, in u. + density : float + Mass density of the component, in gram centimeter^-3. + + Returns + ------- + float + Scattering length density of layer in e-6 1/angstrom^2. """ # 0.602214076 is avogadros constant times 1e-24 return 0.602214076e6 * density * scattering_length / molecular_weight diff --git a/src/easyreflectometry/special/parsing.py b/src/easyreflectometry/special/parsing.py index 0d52195e..fd0cd576 100644 --- a/src/easyreflectometry/special/parsing.py +++ b/src/easyreflectometry/special/parsing.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import re from typing import Tuple @@ -9,9 +11,17 @@ def _dictify(tuples: Tuple[Tuple[str, str]]) -> dict: - """ - :param tuples: tuples of tuples with atom and occurance. - :return: Dict of atoms and occurance. + """Dictify function. + + Parameters + ---------- + tuples : Tuple[Tuple[str, str]] + Tuples of tuples with atom and occurance. + + Returns + ------- + dict + Dict of atoms and occurance. """ res = dict() for atom, n in tuples: @@ -23,19 +33,37 @@ def _dictify(tuples: Tuple[Tuple[str, str]]) -> dict: def _fuse(mol1: dict, mol2: dict, w: int = 1) -> dict: - """ - :param mol1: First dict to fuse - :param mol2: Second dict to fuse - :param w: Weight for dicts - :return: Fused dictionaries + """Fuse function. + + Parameters + ---------- + mol1 : dict + First dict to fuse. + mol2 : dict + Second dict to fuse. + w : int, optional + Weight for dicts. By default, 1. + + Returns + ------- + dict + Fused dictionaries. """ return {atom: (mol1.get(atom, 0) + mol2.get(atom, 0)) * w for atom in set(mol1) | set(mol2)} def _parse(formula: str) -> Tuple[dict, int]: - """ - :param formula: Chemical formula as a string - :return: Tuple containing; formula as a dictwith occurences + """Parse function. + + Parameters + ---------- + formula : str + Chemical formula as a string. + + Returns + ------- + + Tuple containing; formula as a dictwith occurences of each atom and an iterator. """ token_list = [] @@ -73,8 +101,16 @@ def _parse(formula: str) -> Tuple[dict, int]: def parse_formula(formula: str) -> dict: - """ - :param formula: Chemical formula as a string - :return: Formula as a dict with occurences of each atom. + """Parse formula. + + Parameters + ---------- + formula : str + Chemical formula as a string. + + Returns + ------- + dict + Formula as a dict with occurences of each atom. """ return _parse(formula)[0] diff --git a/src/easyreflectometry/summary/__init__.py b/src/easyreflectometry/summary/__init__.py index af9d5fa4..7f333368 100644 --- a/src/easyreflectometry/summary/__init__.py +++ b/src/easyreflectometry/summary/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .summary import Summary -__all__ = [Summary] +__all__ = ['Summary'] diff --git a/src/easyreflectometry/summary/html_templates.py b/src/easyreflectometry/summary/html_templates.py index dc8afc0e..9b770c01 100644 --- a/src/easyreflectometry/summary/html_templates.py +++ b/src/easyreflectometry/summary/html_templates.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + HTML_TEMPLATE = """ @@ -39,7 +42,7 @@ experiments_section - +

Refinement

@@ -49,7 +52,7 @@ figures_section - + """ @@ -75,18 +78,18 @@ HTML_PARAMETER_HEADER_TEMPLATE = """ - parameter_name + parameter_name parameter_value - parameter_unit + parameter_unit parameter_error """ HTML_PARAMETER_TEMPLATE = """ - parameter_name + parameter_name parameter_value - parameter_unit + parameter_unit parameter_error """ diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index 34da2974..394c9d78 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import matplotlib.pyplot as plt import numpy as np from easyscience import global_object @@ -16,9 +19,11 @@ class Summary: def __init__(self, project: Project): + """Init function.""" self._project = project def compile_html_summary(self, figures: bool = False) -> str: + """Compile html summary.""" html = HTML_TEMPLATE html = html.replace('project_information_section', self._project_information_section()) @@ -40,11 +45,13 @@ def compile_html_summary(self, figures: bool = False) -> str: return html def save_html_summary(self, filename: str) -> None: + """Save html summary.""" html = self.compile_html_summary(figures=True) with open(filename, 'w') as f: f.write(html) def save_pdf_summary(self, filename: str) -> None: + """Save pdf summary.""" html = self.compile_html_summary(figures=True) with open(filename, 'w+b') as result_file: @@ -57,6 +64,7 @@ def save_pdf_summary(self, filename: str) -> None: print('An error occured when generating PDF summary!') def save_sld_plot(self, filename: str) -> None: + """Save sld plot.""" fig = plt.figure() ax = fig.add_subplot(1, 1, 1) @@ -70,6 +78,7 @@ def save_sld_plot(self, filename: str) -> None: plt.close() def save_fit_experiment_plot(self, filename: str) -> None: + """Save fit experiment plot.""" fig = plt.figure() ax = fig.add_subplot(1, 1, 1) legends = [] @@ -92,6 +101,7 @@ def save_fit_experiment_plot(self, filename: str) -> None: plt.close() def _project_information_section(self) -> str: + """Project information section.""" html_project = HTML_PROJECT_INFORMATION_TEMPLATE name = self._project._info['name'] @@ -102,6 +112,7 @@ def _project_information_section(self) -> str: return html_project def _sample_section(self) -> str: + """Sample section.""" html_parameters = [] html_parameter = HTML_PARAMETER_HEADER_TEMPLATE @@ -137,6 +148,7 @@ def _sample_section(self) -> str: return html_parameters_str def _experiments_section(self) -> str: + """Experiments section.""" html_experiments = [] for idx, experiment in self._project.experiments.items(): @@ -163,6 +175,7 @@ def _experiments_section(self) -> str: return html_experiments_str def _refinement_section(self) -> str: + """Refinement section.""" html_refinement = HTML_REFINEMENT_TEMPLATE # Get parameters directly from the model @@ -186,6 +199,7 @@ def _refinement_section(self) -> str: return html_refinement def _figures_section(self) -> None: + """Figures section.""" html_figures = HTML_FIGURES_TEMPLATE path_sld = self._project.path / 'sld_plot.jpg' path_fit_experiment = self._project.path / 'fit_experiment_plot.jpg' diff --git a/src/easyreflectometry/utils.py b/src/easyreflectometry/utils.py index 43be7821..43ac58d8 100644 --- a/src/easyreflectometry/utils.py +++ b/src/easyreflectometry/utils.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from copy import deepcopy from numbers import Number from typing import Optional @@ -14,15 +17,16 @@ def get_as_parameter( default_dict: dict, unique_name_prefix: Optional[str] = None, ) -> Parameter: - """ - This function creates a parameter for the variable `name`. A parameter has a value and metadata. + """This function creates a parameter for the variable `name`. + + A parameter has a value and metadata. If the value already is a parameter, it is returned. - If the value is a number, a parameter is created with this value and metadata from the dictionary. - If the value is None, a parameter is created with the default value and metadata from the dictionary. + If the value is a number, a parameter is created with this value and metadata from the dictionary. + If the value is None, a parameter is created with the default value and metadata from the dictionary. - param value: The value to use for the parameter. If None, the default value in the dictionary is used. - param name: The name of the parameter - param default_dict: Dictionary with entry for `name` containing the default value and metadata for the parameter + param value: The value to use for the parameter. If None, the default value in the dictionary is used. + param name: The name of the parameter + param default_dict: Dictionary with entry for `name` containing the default value and metadata for the parameter """ # This is a parameter, return it if isinstance(value, Parameter): @@ -51,17 +55,17 @@ def get_as_parameter( def yaml_dump(dict_repr: dict) -> str: + """Yaml dump.""" return yaml.dump(dict_repr, sort_keys=False, allow_unicode=True) def collect_unique_names_from_dict(structure_dict: dict, unique_names: Optional[list[str]] = None) -> list[str]: - """ - This function returns a list with the 'unique_name' found the input dictionary. - """ + """This function returns a list with the 'unique_name' found the input dictionary.""" if unique_names is None: unique_names = [] def _collect(item): + """Collect function.""" if isinstance(item, dict): if 'unique_name' in item: unique_names.append(item['unique_name']) @@ -76,12 +80,15 @@ def _collect(item): def count_free_parameters(project) -> int: + """Count free parameters.""" return sum(1 for parameter in project.parameters if parameter.free) def count_fixed_parameters(project) -> int: + """Count fixed parameters.""" return sum(1 for parameter in project.parameters if not parameter.free) def count_parameter_user_constraints(project) -> int: + """Count parameter user constraints.""" return sum(1 for parameter in project.parameters if not parameter.independent) diff --git a/tests/calculators/bornagain/test_bornagain_calculator.py b/tests/calculators/bornagain/test_bornagain_calculator.py index e16cdc70..6a7c1aa9 100644 --- a/tests/calculators/bornagain/test_bornagain_calculator.py +++ b/tests/calculators/bornagain/test_bornagain_calculator.py @@ -1,9 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for BornAgain calculator. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' # import os # import unittest diff --git a/tests/calculators/bornagain/test_bornagain_wrapper.py b/tests/calculators/bornagain/test_bornagain_wrapper.py index 84b2a2d7..c52c084c 100644 --- a/tests/calculators/bornagain/test_bornagain_wrapper.py +++ b/tests/calculators/bornagain/test_bornagain_wrapper.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for the BornAgain wrapper. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - # import unittest # import numpy as np diff --git a/tests/calculators/refl1d/test_refl1d_calculator.py b/tests/calculators/refl1d/test_refl1d_calculator.py index ba8c8d35..50de2db4 100644 --- a/tests/calculators/refl1d/test_refl1d_calculator.py +++ b/tests/calculators/refl1d/test_refl1d_calculator.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Refnx calculator. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest import numpy as np diff --git a/tests/calculators/refl1d/test_refl1d_wrapper.py b/tests/calculators/refl1d/test_refl1d_wrapper.py index e19dfe42..57c43ee8 100644 --- a/tests/calculators/refl1d/test_refl1d_wrapper.py +++ b/tests/calculators/refl1d/test_refl1d_wrapper.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Refl1d wrapper. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest from unittest.mock import MagicMock from unittest.mock import patch diff --git a/tests/calculators/refnx/test_refnx_calculator.py b/tests/calculators/refnx/test_refnx_calculator.py index 27283c10..baeb9296 100644 --- a/tests/calculators/refnx/test_refnx_calculator.py +++ b/tests/calculators/refnx/test_refnx_calculator.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Refnx calculator. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest import numpy as np diff --git a/tests/calculators/refnx/test_refnx_wrapper.py b/tests/calculators/refnx/test_refnx_wrapper.py index 74b50ec9..f9d2a4cc 100644 --- a/tests/calculators/refnx/test_refnx_wrapper.py +++ b/tests/calculators/refnx/test_refnx_wrapper.py @@ -1,11 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Refnx wrapper. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - - import unittest import numpy as np @@ -290,7 +289,7 @@ def test_sld_profile(self): assert_almost_equal(p.sld_profile('MyModel')[1][0], 0) assert_almost_equal(p.sld_profile('MyModel')[1][-1], 4) - ### Tests from https://github.com/reflectivity/analysis/tree/master/validation/test/unpolarised + # Tests from https://github.com/reflectivity/analysis/tree/master/validation/test/unpolarised def test_calculate_github_test0(self): p = RefnxWrapper() p.create_material('Material1') @@ -327,15 +326,13 @@ def test_calculate_github_test0(self): p.add_item('Item4', 'MyModel') p.set_resolution_function(PercentageFwhm(0)) p.update_model('MyModel', bkg=0) - q = np.array( - [ - 5.000000000000000104e-03, - 3.717499999999999971e-02, - 5.449999999999999983e-02, - 1.005349999999999994e-01, - 2.955650000000000222e-01, - ] - ) + q = np.array([ + 5.000000000000000104e-03, + 3.717499999999999971e-02, + 5.449999999999999983e-02, + 1.005349999999999994e-01, + 2.955650000000000222e-01, + ]) expected = [ 9.665000503913141472e-01, 3.486325360684768590e-04, @@ -365,15 +362,13 @@ def test_calculate_github_test2(self): p.add_item('Item2', 'MyModel') p.set_resolution_function(PercentageFwhm(0)) p.update_model('MyModel', bkg=0) - q = np.array( - [ - 5.000000000000000104e-03, - 7.564500000000000390e-02, - 1.433050000000000157e-01, - 2.368350000000000177e-01, - 5.920499999999999652e-01, - ] - ) + q = np.array([ + 5.000000000000000104e-03, + 7.564500000000000390e-02, + 1.433050000000000157e-01, + 2.368350000000000177e-01, + 5.920499999999999652e-01, + ]) expected = [ 1.000000000000000222e00, 1.964576414578978456e-04, diff --git a/tests/data/test_data_store.py b/tests/data/test_data_store.py index ea66f8ff..66ba9b04 100644 --- a/tests/data/test_data_store.py +++ b/tests/data/test_data_store.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import Mock import numpy as np @@ -29,7 +32,13 @@ def test_constructor_default_values(self): def test_constructor_with_values(self): # When data = DataSet1D( - x=[1, 2, 3], y=[4, 5, 6], ye=[7, 8, 9], xe=[10, 11, 12], x_label='label_x', y_label='label_y', name='MyDataSet1D' + x=[1, 2, 3], + y=[4, 5, 6], + ye=[7, 8, 9], + xe=[10, 11, 12], + x_label='label_x', + y_label='label_y', + name='MyDataSet1D', ) # Then diff --git a/tests/functional/test_dummy.py b/tests/functional/test_dummy.py new file mode 100644 index 00000000..6927fe89 --- /dev/null +++ b/tests/functional/test_dummy.py @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + + +def test_dummy(): + calculated = 2 + 2 + expected = 4 + assert calculated == expected diff --git a/tests/integration/fitting/test_dummy.py b/tests/integration/fitting/test_dummy.py new file mode 100644 index 00000000..2256189c --- /dev/null +++ b/tests/integration/fitting/test_dummy.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +import pytest + + +@pytest.mark.fast +def test_dummy_fast(): + calculated = 2 + 2 + expected = 4 + assert calculated == expected + + +def test_dummy_slow(): + calculated = sum(i * j for i in range(10000) for j in range(10000)) + expected = 2499500025000000 + assert calculated == expected diff --git a/tests/integration/scipp-analysis/test_dummy.py b/tests/integration/scipp-analysis/test_dummy.py new file mode 100644 index 00000000..2256189c --- /dev/null +++ b/tests/integration/scipp-analysis/test_dummy.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +import pytest + + +@pytest.mark.fast +def test_dummy_fast(): + calculated = 2 + 2 + expected = 4 + assert calculated == expected + + +def test_dummy_slow(): + calculated = sum(i * j for i in range(10000) for j in range(10000)) + expected = 2499500025000000 + assert calculated == expected diff --git a/tests/model/test_model.py b/tests/model/test_model.py index 49ce60fc..2d623512 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Model class. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest from unittest.mock import MagicMock diff --git a/tests/model/test_model_collection.py b/tests/model/test_model_collection.py index cc98534d..4a6fd521 100644 --- a/tests/model/test_model_collection.py +++ b/tests/model/test_model_collection.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from easyscience import global_object from easyreflectometry.model.model import COLORS @@ -113,7 +116,10 @@ def test_as_dict(self): dict_repr = collection.as_dict() # Expect - assert dict_repr['data'][0]['resolution_function'] == {'smearing': 'PercentageFwhm', 'constant': 5.0} + assert dict_repr['data'][0]['resolution_function'] == { + 'smearing': 'PercentageFwhm', + 'constant': 5.0, + } def test_dict_round_trip(self): # When diff --git a/tests/model/test_resolution_functions.py b/tests/model/test_resolution_functions.py index 6ff8afd1..e28a99f2 100644 --- a/tests/model/test_resolution_functions.py +++ b/tests/model/test_resolution_functions.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import unittest import numpy as np @@ -64,7 +67,11 @@ def test_as_dict(self): resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) # Then Expect - resolution_function.as_dict() == {'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10]} + resolution_function.as_dict() == { + 'smearing': 'LinearSpline', + 'q_data_points': [0, 10], + 'fwhm_values': [5, 10], + } def test_dict_round_trip(self): # When @@ -90,7 +97,8 @@ def test_constructor(self): # Then Expect assert np.allclose( - np.array(resolution_function.smearing()), np.array([2.51664683, 2.84038734, 3.2460762, 3.6796519, 4.07869271]) + np.array(resolution_function.smearing()), + np.array([2.51664683, 2.84038734, 3.2460762, 3.6796519, 4.07869271]), ) def test_as_dict(self): diff --git a/tests/package_test.py b/tests/package_test.py index 4d77705c..f18f84f8 100644 --- a/tests/package_test.py +++ b/tests/package_test.py @@ -1,5 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2024 Easyscience contributors (https://github.com/EasyScience) + import easyreflectometry as pkg diff --git a/tests/sample/assemblies/test_base_assembly.py b/tests/sample/assemblies/test_base_assembly.py index 178f6382..482cf669 100644 --- a/tests/sample/assemblies/test_base_assembly.py +++ b/tests/sample/assemblies/test_base_assembly.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for BaseAssembly class module """ diff --git a/tests/sample/assemblies/test_bilayer.py b/tests/sample/assemblies/test_bilayer.py index b96e6a78..03949ee7 100644 --- a/tests/sample/assemblies/test_bilayer.py +++ b/tests/sample/assemblies/test_bilayer.py @@ -1,9 +1,11 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Bilayer class module """ __author__ = 'github.com/easyscience' -__version__ = '0.0.1' from easyscience import global_object diff --git a/tests/sample/assemblies/test_gradient_layer.py b/tests/sample/assemblies/test_gradient_layer.py index 3b88df47..7efda4a9 100644 --- a/tests/sample/assemblies/test_gradient_layer.py +++ b/tests/sample/assemblies/test_gradient_layer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for GradientLayer class module """ @@ -168,7 +171,11 @@ def test_prepare_gradient_layers(monkeypatch): mock_LayerCollection = MagicMock() mock_Material = MagicMock(return_value='Material_from_mock') mock_linear_gradient = MagicMock(return_value=[1.0, 2.0, 3.0]) - monkeypatch.setattr(easyreflectometry.sample.assemblies.gradient_layer, '_linear_gradient', mock_linear_gradient) + monkeypatch.setattr( + easyreflectometry.sample.assemblies.gradient_layer, + '_linear_gradient', + mock_linear_gradient, + ) monkeypatch.setattr(easyreflectometry.sample.assemblies.gradient_layer, 'Layer', mock_Layer) monkeypatch.setattr(easyreflectometry.sample.assemblies.gradient_layer, 'Material', mock_Material) monkeypatch.setattr(easyreflectometry.sample.assemblies.gradient_layer, 'LayerCollection', mock_LayerCollection) diff --git a/tests/sample/assemblies/test_multilayer.py b/tests/sample/assemblies/test_multilayer.py index 82f807a4..f2d7bd61 100644 --- a/tests/sample/assemblies/test_multilayer.py +++ b/tests/sample/assemblies/test_multilayer.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for MultiLayer class module """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest from easyscience import global_object diff --git a/tests/sample/assemblies/test_repeating_multilayer.py b/tests/sample/assemblies/test_repeating_multilayer.py index 6eb17d0a..3ee2858b 100644 --- a/tests/sample/assemblies/test_repeating_multilayer.py +++ b/tests/sample/assemblies/test_repeating_multilayer.py @@ -1,11 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for RepeatingMultiLayer module """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - - import unittest from easyscience import global_object diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index 3a0549cd..62b92689 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -1,11 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for SurfactantLayer class module """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - - import unittest from easyscience import global_object @@ -111,7 +110,12 @@ def test_dict_repr(self): 'solvent_fraction': '0.200 dimensionless', 'sld': '2.269e-6 1/Å^2', 'isld': '0.000e-6 1/Å^2', - 'material': {'C10H18NO8P': {'sld': '1.246e-6 1/Å^2', 'isld': '0.000e-6 1/Å^2'}}, + 'material': { + 'C10H18NO8P': { + 'sld': '1.246e-6 1/Å^2', + 'isld': '0.000e-6 1/Å^2', + } + }, 'solvent': {'D2O': {'sld': '6.360e-6 1/Å^2', 'isld': '0.000e-6 1/Å^2'}}, } }, diff --git a/tests/sample/collections/test_base_collection.py b/tests/sample/collections/test_base_collection.py index b9ad429e..44b8e208 100644 --- a/tests/sample/collections/test_base_collection.py +++ b/tests/sample/collections/test_base_collection.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import MagicMock from easyreflectometry.sample.collections.base_collection import BaseCollection diff --git a/tests/sample/collections/test_layer_collection.py b/tests/sample/collections/test_layer_collection.py index 543e9235..7eb8071b 100644 --- a/tests/sample/collections/test_layer_collection.py +++ b/tests/sample/collections/test_layer_collection.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for LayerCollection class. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest from easyscience import global_object diff --git a/tests/sample/collections/test_material_collection.py b/tests/sample/collections/test_material_collection.py index 25f30b59..3ca9f22b 100644 --- a/tests/sample/collections/test_material_collection.py +++ b/tests/sample/collections/test_material_collection.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for LayerCollection class. """ diff --git a/tests/sample/collections/test_sample.py b/tests/sample/collections/test_sample.py index 3cb1d0c1..6f64dd25 100644 --- a/tests/sample/collections/test_sample.py +++ b/tests/sample/collections/test_sample.py @@ -1,11 +1,10 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Sample class. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - - import pytest from easyscience import global_object from numpy.testing import assert_equal diff --git a/tests/sample/elements/layers/test_layer.py b/tests/sample/elements/layers/test_layer.py index 1cbecb17..26a5cf0a 100644 --- a/tests/sample/elements/layers/test_layer.py +++ b/tests/sample/elements/layers/test_layer.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Layer class. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - import unittest import numpy as np diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index 505eec5d..4d0abf7d 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for LayerAreaPerMolecule class. """ diff --git a/tests/sample/elements/materials/test_material.py b/tests/sample/elements/materials/test_material.py index c07a2217..997102a4 100644 --- a/tests/sample/elements/materials/test_material.py +++ b/tests/sample/elements/materials/test_material.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Tests for Material class. """ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' - from easyscience import global_object from easyreflectometry.sample.elements.materials.material import DEFAULTS diff --git a/tests/sample/elements/materials/test_material_density.py b/tests/sample/elements/materials/test_material_density.py index d1945e1e..99c6615a 100644 --- a/tests/sample/elements/materials/test_material_density.py +++ b/tests/sample/elements/materials/test_material_density.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import unittest import numpy as np diff --git a/tests/sample/elements/materials/test_material_mixture.py b/tests/sample/elements/materials/test_material_mixture.py index 423bfb2d..0e70a2b7 100644 --- a/tests/sample/elements/materials/test_material_mixture.py +++ b/tests/sample/elements/materials/test_material_mixture.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import MagicMock from easyscience import global_object diff --git a/tests/sample/elements/materials/test_material_solvated.py b/tests/sample/elements/materials/test_material_solvated.py index a50211d5..3d4a9917 100644 --- a/tests/sample/elements/materials/test_material_solvated.py +++ b/tests/sample/elements/materials/test_material_solvated.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import MagicMock import pytest diff --git a/tests/special/test_calculations.py b/tests/special/test_calculations.py index e7f1f89f..10ca1ca1 100644 --- a/tests/special/test_calculations.py +++ b/tests/special/test_calculations.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2022 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import unittest diff --git a/tests/summary/test_summary.py b/tests/summary/test_summary.py index 3bbb186e..8a8f581f 100644 --- a/tests/summary/test_summary.py +++ b/tests/summary/test_summary.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import os from unittest.mock import MagicMock diff --git a/tests/test_data.py b/tests/test_data.py index 0ee95d94..d08402f2 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -1,5 +1,6 @@ -__author__ = 'github.com/arm61' -__version__ = '0.0.1' +# SPDX-FileCopyrightText: 2022 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import os import unittest @@ -224,7 +225,10 @@ def test_load_txt_three_columns(self): assert coords_name in er_data['coords'] # xe should be zeros for 3-column file - assert_almost_equal(er_data['coords'][coords_name].variances, np.zeros_like(er_data['coords'][coords_name].values)) + assert_almost_equal( + er_data['coords'][coords_name].variances, + np.zeros_like(er_data['coords'][coords_name].values), + ) def test_load_txt_with_zero_errors(self): fpath = os.path.join(PATH_STATIC, 'ref_zero_var.txt') diff --git a/tests/test_fitting.py b/tests/test_fitting.py index 2a03a98c..28dfe0fa 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -1,4 +1,6 @@ -__author__ = 'github.com/arm61' +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import os from unittest.mock import MagicMock @@ -175,12 +177,10 @@ def test_fitting_with_manual_zero_variance(): variances[30:32] = 0.0 # 2 more zero variance points # Create scipp DataGroup manually - data = sc.DataGroup( - { - 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz_values)}, - 'data': {'R_0': sc.array(dims=['Qz_0'], values=r_values, variances=variances)}, - } - ) + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz_values)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r_values, variances=variances)}, + }) # Create a simple model for fitting si = Material(2.07, 0, 'Si') @@ -428,7 +428,12 @@ def test_prepare_fit_arrays_legacy_mask_drops_zero_variance(): assert np.allclose(x_out, [0.01, 0.03]) assert np.allclose(y_eff, [1.0, 0.6]) assert np.allclose(weights, [1.0 / np.sqrt(0.01), 1.0 / np.sqrt(0.04)]) - assert stats == {'valid': 2, 'mighell_substituted': 0, 'masked': 1, 'transformed_all_points': False} + assert stats == { + 'valid': 2, + 'mighell_substituted': 0, + 'masked': 1, + 'transformed_all_points': False, + } def test_prepare_fit_arrays_hybrid_transforms_zero_variance(): @@ -449,7 +454,12 @@ def test_prepare_fit_arrays_hybrid_transforms_zero_variance(): assert y_eff[1] == pytest.approx(0.8 + 0.8) # sigma = sqrt(y + 1) = sqrt(1.8) assert weights[1] == pytest.approx(1.0 / np.sqrt(1.8)) - assert stats == {'valid': 2, 'mighell_substituted': 1, 'masked': 0, 'transformed_all_points': False} + assert stats == { + 'valid': 2, + 'mighell_substituted': 1, + 'masked': 0, + 'transformed_all_points': False, + } def test_prepare_fit_arrays_mighell_transforms_all(): @@ -466,7 +476,12 @@ def test_prepare_fit_arrays_mighell_transforms_all(): # sigma = sqrt(y + 1) assert weights[0] == pytest.approx(1.0 / np.sqrt(1.5)) assert weights[1] == pytest.approx(1.0 / np.sqrt(1.3)) - assert stats == {'valid': 0, 'mighell_substituted': 2, 'masked': 0, 'transformed_all_points': True} + assert stats == { + 'valid': 0, + 'mighell_substituted': 2, + 'masked': 0, + 'transformed_all_points': True, + } def test_fit_single_data_set_1d_hybrid_keeps_zero_variance_points(): @@ -553,13 +568,17 @@ def test_classical_and_objective_chi_are_split_for_fit_results(): fitter._models = [MagicMock(unique_name='model_0', as_dict=MagicMock(return_value={'name': 'model_0'}))] fitter._fit_func = [lambda x: np.array([0.8, 0.75, 0.7])] - data = sc.DataGroup( - { - 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.array([0.01, 0.02, 0.03]), unit=sc.Unit('1/angstrom'))}, - 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.array([1.0, 0.9, 0.7]), variances=np.array([0.01, 0.0, 0.04]))}, - 'attrs': {}, - } - ) + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.array([0.01, 0.02, 0.03]), unit=sc.Unit('1/angstrom'))}, + 'data': { + 'R_0': sc.array( + dims=['Qz_0'], + values=np.array([1.0, 0.9, 0.7]), + variances=np.array([0.01, 0.0, 0.04]), + ) + }, + 'attrs': {}, + }) analysed = fitter.fit(data) @@ -654,12 +673,10 @@ def test_fit_multi_dataset_hybrid_uses_transformed_y_and_weights(): variances = np.ones_like(r_values) * 0.01 variances[3:5] = 0.0 # 2 zero-variance points - data = sc.DataGroup( - { - 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz_values)}, - 'data': {'R_0': sc.array(dims=['Qz_0'], values=r_values, variances=variances)}, - } - ) + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz_values)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r_values, variances=variances)}, + }) model = Model() model.interface = CalculatorFactory() diff --git a/tests/test_limits.py b/tests/test_limits.py index e8320eb7..2fd1cc74 100644 --- a/tests/test_limits.py +++ b/tests/test_limits.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np import pytest from easyscience import global_object diff --git a/tests/test_measurement_comprehensive.py b/tests/test_measurement_comprehensive.py index d6bb0c46..baffb2b8 100644 --- a/tests/test_measurement_comprehensive.py +++ b/tests/test_measurement_comprehensive.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ Comprehensive tests for measurement and data store functionality. Tests for all functions in measurement.py and data_store.py modules. @@ -113,7 +116,10 @@ def test_load_txt_handles_three_columns(self): coords_key = list(result['coords'].keys())[0] # xe should be zeros - assert_array_equal(result['coords'][coords_key].variances, np.zeros_like(result['coords'][coords_key].values)) + assert_array_equal( + result['coords'][coords_key].variances, + np.zeros_like(result['coords'][coords_key].values), + ) def test_load_txt_with_insufficient_columns(self): """Test that _load_txt raises error for files with too few columns.""" @@ -159,7 +165,16 @@ def test_constructor_all_parameters(self): xe = [0.1, 0.1, 0.1, 0.1] ye = [1, 2, 3, 4] - dataset = DataSet1D(name='TestData', x=x, y=y, xe=xe, ye=ye, x_label='Q (Å⁻¹)', y_label='Reflectivity', model=None) + dataset = DataSet1D( + name='TestData', + x=x, + y=y, + xe=xe, + ye=ye, + x_label='Q (Å⁻¹)', + y_label='Reflectivity', + model=None, + ) assert dataset.name == 'TestData' assert_array_equal(dataset.x, np.array(x)) @@ -233,7 +248,8 @@ def test_datastore_as_sequence(self): assert store[0].name == 'item2' def test_datastore_experiments_and_simulations_filtering(self): - """Test experiments and simulations properties filter correctly.""" + """Test experiments and simulations properties + filter correctly.""" exp1 = DataSet1D(name='exp1', x=[1], y=[2], model=Mock()) exp2 = DataSet1D(name='exp2', x=[3], y=[4], model=Mock()) sim1 = DataSet1D(name='sim1', x=[5], y=[6]) @@ -264,7 +280,8 @@ class TestProjectDataComprehensive: """Comprehensive tests for ProjectData class.""" def test_project_data_initialization(self): - """Test ProjectData initializes with correct default values.""" + """Test ProjectData initializes with correct + default values.""" project = ProjectData() assert project.name == 'DataStore' @@ -274,7 +291,8 @@ def test_project_data_initialization(self): assert project.sim_data.name == 'Sim Datastore' def test_project_data_with_custom_stores(self): - """Test ProjectData with custom experiment and simulation stores.""" + """Test ProjectData with custom experiment and + simulation stores.""" custom_exp = DataStore(name='CustomExp') custom_sim = DataStore(name='CustomSim') @@ -303,7 +321,8 @@ class TestIntegrationScenarios: """Integration tests for common usage scenarios.""" def test_complete_workflow_orso_file(self): - """Test complete workflow: load ORSO file -> create dataset -> store in project.""" + """Test complete workflow: load ORSO file + -> create dataset -> store in project.""" # Load file fpath = os.path.join(PATH_STATIC, 'test_example1.ort') dataset = load_as_dataset(fpath) @@ -318,7 +337,8 @@ def test_complete_workflow_orso_file(self): assert isinstance(project.exp_data[0], DataSet1D) def test_complete_workflow_txt_file(self): - """Test complete workflow: load txt file -> create dataset -> store in project.""" + """Test complete workflow: load txt file -> + create dataset -> store in project.""" # Load file fpath = os.path.join(PATH_STATIC, 'ref_concat_1.txt') dataset = load_as_dataset(fpath) diff --git a/tests/test_orso_utils.py b/tests/test_orso_utils.py index ebb662a1..4ad2e9ab 100644 --- a/tests/test_orso_utils.py +++ b/tests/test_orso_utils.py @@ -1,5 +1,5 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2025 DMSC import os import warnings @@ -91,10 +91,12 @@ def test_load_data_from_orso_file(): def test_orso_sld_unit_conversion(orso_data): - """Test that SLD values from ORSO are correctly converted from A^-2 to 10^-6 A^-2. + """Test that SLD values from ORSO are correctly converted + from A^-2 to 10^-6 A^-2. ORSO stores SLD in absolute units (A^-2), e.g., 3.47e-06. - The internal representation uses 10^-6 A^-2, so the value should be 3.47. + The internal representation uses 10^-6 A^-2, + so the value should be 3.47. """ sample = load_orso_model(orso_data) @@ -114,9 +116,7 @@ def test_orso_sld_unit_conversion(orso_data): subphase = sample[2] si_layer = subphase.layers[0] assert si_layer.material.name == 'Si' - assert abs(si_layer.material.sld.value - 2.07) < 1e-6, ( - f'Expected SLD ~2.07 (10^-6 A^-2), got {si_layer.material.sld.value}' - ) + assert abs(si_layer.material.sld.value - 2.07) < 1e-6, f'Expected SLD ~2.07 (10^-6 A^-2), got {si_layer.material.sld.value}' # Check air superphase layer # ORSO file has: sld: {real: 0.0, imag: 0.0} @@ -152,7 +152,8 @@ def test_LoadOrso_with_nonexistent_file(): def test_get_sld_values_defaults_to_zero_when_sld_and_density_missing(): - """_get_sld_values should return (0.0, 0.0) when both sld and mass_density are None.""" + """_get_sld_values should return (0.0, 0.0) when both + sld and mass_density are None.""" material = SimpleNamespace(sld=None, mass_density=None) m_sld, m_isld = _get_sld_values(material, 'Unknown') assert m_sld == 0.0 @@ -160,7 +161,8 @@ def test_get_sld_values_defaults_to_zero_when_sld_and_density_missing(): def test_load_orso_model_returns_none_and_warns_when_no_sample_model(): - """load_orso_model should return None and emit a warning when the ORSO file has no sample model.""" + """load_orso_model should return None and emit a warning + when the ORSO file has no sample model.""" orso_data = orso.load_orso(os.path.join(PATH_STATIC, 'test_example1.ort')) # Verify the file indeed has no model assert orso_data[0].info.data_source.sample.model is None diff --git a/tests/test_ort_file.py b/tests/test_ort_file.py index 8ef1de16..b1277033 100644 --- a/tests/test_ort_file.py +++ b/tests/test_ort_file.py @@ -1,5 +1,5 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2025 DMSC import logging @@ -154,7 +154,8 @@ def test_validate_physical_data__r_values_ureal_positive(load_data): for val_a, val_b in zip(a, b): if val_a > val_b: pytest.warns( - UserWarning, reason=f'Reflectivity value {val_a} is unphysically large compared to its uncertainty {val_b}' + UserWarning, + reason=f'Reflectivity value {val_a} is unphysically large compared to its uncertainty {val_b}', ) assert all(load_data['data']['R_0'].values <= 1 + 2 * np.sqrt(load_data['data']['R_0'].variances)) diff --git a/tests/test_parameter_utils.py b/tests/test_parameter_utils.py index d8d2ce97..72e3bbc0 100644 --- a/tests/test_parameter_utils.py +++ b/tests/test_parameter_utils.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np import pytest from numpy.testing import assert_equal diff --git a/tests/test_project.py b/tests/test_project.py index 3c390960..73aeca85 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import datetime import os from pathlib import Path @@ -133,7 +136,8 @@ def remove_interface(d): models_dict['unique_name'] = 'project_models' remove_interface(project_models_dict) remove_interface(models_dict) - # Since as_dict may not include unique_name, remove it for comparison + # Since as_dict may not include unique_name, + # remove it for comparison for d in [project_models_dict, models_dict]: if 'unique_name' in d: del d['unique_name'] @@ -171,7 +175,12 @@ def test_sld_data_for_model_at_index(self): assert len(sample_data.x) == 500 assert_allclose( np.array([4.6119497e-08, 6.3189932e00, 6.3350000e00, 2.0740000e00]), - np.array([sample_data.y[0], sample_data.y[100], sample_data.y[300], sample_data.y[499]]), + np.array([ + sample_data.y[0], + sample_data.y[100], + sample_data.y[300], + sample_data.y[499], + ]), ) def test_sample_data_for_model_at_index(self): @@ -200,7 +209,12 @@ def test_model_data_for_model_at_index(self): # Expect assert len(model_data.y) == 4 assert_allclose( - np.array([0.9738701849233727, 0.0017678986451491123, 0.00016581714423990004, 3.3290653551465554e-08]), + np.array([ + 0.9738701849233727, + 0.0017678986451491123, + 0.00016581714423990004, + 3.3290653551465554e-08, + ]), model_data.y, ) @@ -558,7 +572,8 @@ def test_load_from_json(self, tmp_path): # Then new_project.load_from_json(tmp_path / 'name' / 'project.json') - # Do it twice to ensure that potential global objects don't collide + # Do it twice to ensure that potential + # global objects don't collide new_project.load_from_json(tmp_path / 'name' / 'project.json') # Expect @@ -904,11 +919,13 @@ def test_add_sample_from_orso_with_shared_materials(self): # Expect - shared material should not be duplicated assert len(project._models) == 2 - # The shared material instance is already in the collection, so count should stay the same + # The shared material instance is already in the collection, + # so count should stay the same assert len(project._materials) == initial_material_count def test_replace_models_from_orso(self): - """Test that replace_models_from_orso replaces all existing models with a single new model.""" + """Test that replace_models_from_orso replaces all existing + models with a single new model.""" # When global_object.map._clear() project = Project() @@ -1077,7 +1094,12 @@ def test_remove_model_at_index_removes_experiment_at_same_index(self): project._models.append(model) # Add experiment linked to model 0 experiment = DataSet1D( - name='exp0', x=[0.01, 0.02], y=[1.0, 0.5], ye=[0.1, 0.1], xe=[0.001, 0.001], model=project._models[0] + name='exp0', + x=[0.01, 0.02], + y=[1.0, 0.5], + ye=[0.1, 0.1], + xe=[0.001, 0.001], + model=project._models[0], ) project._experiments[0] = experiment diff --git a/tests/test_topmost_nesting.py b/tests/test_topmost_nesting.py index 5c38ec0b..622991b2 100644 --- a/tests/test_topmost_nesting.py +++ b/tests/test_topmost_nesting.py @@ -1,5 +1,8 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + """ -Tests exercising the methods of the topmost classes for nested structure. +Testing the methods of the topmost classes for nested structure. To ensure that the parameters are relayed. """ diff --git a/tests/test_utils.py b/tests/test_utils.py index 64bd7791..4d9c4828 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from easyreflectometry import Project from easyreflectometry.utils import count_fixed_parameters from easyreflectometry.utils import count_free_parameters @@ -27,16 +30,3 @@ def test_count_fixed_parameters(): # Expect assert count == 13 - - -def test_count_parameter_user_constraints(): - # When - project = Project() - project.default_model() - # project.parameters[0].user_constraints['name_other_parameter'] = 'constraint' - - # # Then - # count = count_parameter_user_constraints(project) - - # # Expect - # assert count == 1 diff --git a/tests/unit/test_dummy.py b/tests/unit/test_dummy.py new file mode 100644 index 00000000..6927fe89 --- /dev/null +++ b/tests/unit/test_dummy.py @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + + +def test_dummy(): + calculated = 2 + 2 + expected = 4 + assert calculated == expected diff --git a/tools/license_headers.py b/tools/license_headers.py new file mode 100644 index 00000000..f276ca1b --- /dev/null +++ b/tools/license_headers.py @@ -0,0 +1,321 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Add, remove, or check SPDX headers in Python files.""" + +from __future__ import annotations + +import argparse +import fnmatch +import tomllib +from datetime import datetime +from pathlib import Path +from typing import Any +from typing import Optional +from typing import Union + +from git import Repo +from spdx_headers.core import find_repository_root +from spdx_headers.core import get_copyright_info +from spdx_headers.core import has_spdx_header +from spdx_headers.data import load_license_data +from spdx_headers.operations import add_header_to_single_file +from spdx_headers.operations import remove_header_from_single_file + +LICENSE_DATABASE = load_license_data() + + +def load_pyproject(repo_path: Union[str, Path]) -> dict[str, Any]: + """ + Load and return parsed ``pyproject.toml`` data for the repository. + """ + repo_root = find_repository_root(repo_path) + pyproject_path = repo_root / 'pyproject.toml' + + with pyproject_path.open('rb') as file_handle: + return tomllib.load(file_handle) + + +def get_pyproject_value(pyproject_data: dict[str, Any], dotted_key: str) -> Any: + """Return a nested ``pyproject.toml`` value from a dotted key.""" + value: Any = pyproject_data + for part in dotted_key.split('.'): + if not isinstance(value, dict) or part not in value: + raise KeyError(dotted_key) + value = value[part] + return value + + +def normalize_pattern(pattern: str) -> str: + """Normalize an exclude pattern to a POSIX-style relative path.""" + normalized = Path(pattern).as_posix() + if normalized.startswith('./'): + normalized = normalized[2:] + return normalized.rstrip('/') + + +def get_exclude_patterns( + repo_path: Union[str, Path], + exclude_values: list[str], + exclude_from_pyproject_toml: Optional[str], +) -> list[str]: + """ + Return normalized exclude patterns from CLI and ``pyproject.toml``. + """ + pyproject_data = load_pyproject(repo_path) + patterns: list[str] = [] + + if exclude_from_pyproject_toml: + value = get_pyproject_value(pyproject_data, exclude_from_pyproject_toml) + if not isinstance(value, list) or not all(isinstance(item, str) for item in value): + raise ValueError( + f'{exclude_from_pyproject_toml} in pyproject.toml must be a list of strings.', + ) + patterns.extend(value) + + for item in exclude_values: + try: + value = get_pyproject_value(pyproject_data, item) + except KeyError: + patterns.append(item) + continue + + if not isinstance(value, list) or not all(isinstance(entry, str) for entry in value): + raise ValueError(f'{item} in pyproject.toml must be a list of strings.') + patterns.extend(value) + + normalized_patterns: list[str] = [] + seen: set[str] = set() + for pattern in patterns: + normalized = normalize_pattern(pattern) + if normalized and normalized not in seen: + normalized_patterns.append(normalized) + seen.add(normalized) + + return normalized_patterns + + +def get_file_creation_year(file_path: Union[str, Path]) -> str: + """Return the year the file was first added to Git history. + + If the year cannot be determined, fall back to the current year. + """ + file_path = Path(file_path) + + repo = Repo(file_path, search_parent_directories=True) + root = Path(repo.working_tree_dir).resolve() + rel_path = file_path.resolve().relative_to(root) + + rel_path_git = rel_path.as_posix() + + log_output = repo.git.log( + '--follow', + '--diff-filter=A', + '--reverse', + '--format=%ad', + '--date=format:%Y', + '--', + rel_path_git, + ).strip() + + year = log_output.splitlines()[0].strip() if log_output else '' + + return year or str(datetime.now().year) + + +def get_org_url(repo_path: Union[str, Path]) -> str: + """ + Return the organization URL derived from the repository source URL. + """ + pyproject_data = load_pyproject(repo_path) + repo_url = pyproject_data['project']['urls']['Source Code'] + return repo_url.rsplit('/', 1)[0] + + +def get_project_license(repo_path: Union[str, Path]) -> str: + """Return the project license value from ``pyproject.toml``.""" + pyproject_data = load_pyproject(repo_path) + return pyproject_data['project']['license'] + + +def get_copyright_holder(repo_path: Union[str, Path]) -> str: + """Return the repository copyright holder name.""" + _, name, _ = get_copyright_info(repo_path) + return name + + +def add_spdx_header( + target_file: Union[str, Path], + *, + license_key: str, + copyright_holder: str, + org_url: str, +) -> None: + """Add SPDX headers to one file.""" + year = get_file_creation_year(target_file) + + add_header_to_single_file( + filepath=target_file, + license_key=license_key, + license_data=LICENSE_DATABASE, + year=year, + name=copyright_holder, + email=org_url, + ) + + +def is_excluded(relative_path: str, exclude_patterns: list[str]) -> bool: + """Return whether a relative path should be excluded.""" + for pattern in exclude_patterns: + if fnmatch.fnmatch(relative_path, pattern): + return True + if relative_path == pattern: + return True + if relative_path.startswith(f'{pattern}/'): + return True + return False + + +def iter_python_files( + paths: list[str], + *, + repo_root: Path, + exclude_patterns: list[str], + parser: argparse.ArgumentParser, +) -> list[Path]: + """Collect Python files under the given paths after exclusions.""" + files: list[Path] = [] + seen: set[Path] = set() + + for base_dir in paths: + base_path = Path(base_dir) + if not base_path.exists(): + parser.error(f'Path does not exist: {base_dir}') + + if base_path.is_file(): + candidates = [base_path] if base_path.suffix == '.py' else [] + else: + candidates = sorted(base_path.rglob('*.py')) + + for py_file in candidates: + resolved = py_file.resolve() + try: + relative_path = resolved.relative_to(repo_root).as_posix() + except ValueError: + relative_path = py_file.as_posix() + + if is_excluded(relative_path, exclude_patterns): + continue + + if resolved not in seen: + files.append(py_file) + seen.add(resolved) + + return files + + +def run_add( + files: list[Path], + *, + license_key: str, + copyright_holder: str, + org_url: str, +) -> int: + """Add SPDX headers to all selected files.""" + for py_file in files: + add_spdx_header( + py_file, + license_key=license_key, + copyright_holder=copyright_holder, + org_url=org_url, + ) + return 0 + + +def run_remove(files: list[Path]) -> int: + """Remove SPDX headers from all selected files.""" + for py_file in files: + remove_header_from_single_file(py_file) + return 0 + + +def run_check(files: list[Path]) -> int: + """Check SPDX headers in all selected files.""" + missing_files = [py_file for py_file in files if not has_spdx_header(py_file)] + + if not missing_files: + print('✓ All Python files have valid SPDX headers.') + return 0 + + print('✗ The following files are missing SPDX headers:') + for py_file in missing_files: + print(f' - {py_file.as_posix()}') + print(f'\nFound {len(missing_files)} files without SPDX headers.') + return 1 + + +def build_parser() -> argparse.ArgumentParser: + """Build the CLI argument parser.""" + parser = argparse.ArgumentParser( + description='Add, remove, or check SPDX headers in Python files.', + ) + subparsers = parser.add_subparsers(dest='command', required=True) + + for command_name in ('check', 'remove', 'add'): + command_parser = subparsers.add_parser(command_name) + command_parser.add_argument( + 'paths', + nargs='+', + help='Relative paths to scan (e.g. src tests)', + ) + command_parser.add_argument( + '--exclude', + nargs='*', + default=[], + help='Exclude paths, glob patterns, or pyproject dotted keys.', + ) + command_parser.add_argument( + '--exclude-from-pyproject-toml', + help='Read exclude patterns from a dotted key in pyproject.toml.', + ) + + return parser + + +def main(argv: Optional[list[str]] = None) -> int: + """Run the SPDX header CLI.""" + parser = build_parser() + args = parser.parse_args(argv) + + repo_path = Path('.').resolve() + repo_root = find_repository_root(repo_path).resolve() + exclude_patterns = get_exclude_patterns( + repo_path, + args.exclude, + args.exclude_from_pyproject_toml, + ) + files = iter_python_files( + args.paths, + repo_root=repo_root, + exclude_patterns=exclude_patterns, + parser=parser, + ) + + if args.command == 'check': + return run_check(files) + + if args.command == 'remove': + return run_remove(files) + + license_key = get_project_license(repo_path) + copyright_holder = get_copyright_holder(repo_path) + org_url = get_org_url(repo_path) + return run_add( + files, + license_key=license_key, + copyright_holder=copyright_holder, + org_url=org_url, + ) + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/tools/update_docs_assets.py b/tools/update_docs_assets.py new file mode 100644 index 00000000..d375093c --- /dev/null +++ b/tools/update_docs_assets.py @@ -0,0 +1,91 @@ +""" +Update documentation assets from the assets-branding repository. + +This script fetches branding assets (logos, icons, images) from the +easyscience/assets-branding GitHub repository and copies them to the +appropriate locations in the documentation directory. +""" + +import shutil +from pathlib import Path + +import pooch + +# Configuration: Define what to fetch and where to copy +GITHUB_REPO = 'easyscience/assets-branding' +GITHUB_BRANCH = 'master' +BASE_URL = f'https://raw.githubusercontent.com/{GITHUB_REPO}/refs/heads/{GITHUB_BRANCH}' +PROJECT_NAME = 'easyreflectometry' + +# Mapping of source files to destination paths +# Format: "source_path_in_repo": "destination_path_in_project" +ASSETS_MAP = { + # Logos + f'{PROJECT_NAME}/logos/dark.svg': 'docs/docs/assets/images/logo_dark.svg', + f'{PROJECT_NAME}/logos/light.svg': 'docs/docs/assets/images/logo_light.svg', + # Favicon + f'{PROJECT_NAME}/icons/color.png': 'docs/docs/assets/images/favicon.png', + # Icon overrides + f'{PROJECT_NAME}/icons/bw.svg': f'docs/overrides/.icons/{PROJECT_NAME}.svg', + 'easyscience-org/icons/eso-icon_bw.svg': 'docs/overrides/.icons/easyscience.svg', +} + + +def fetch_and_copy_asset( + source_path: str, + dest_path: str, + cache_dir: Path, +) -> None: + """ + Fetch an asset from GitHub and copy it to the destination. + + Args: + source_path: Path to the file in the GitHub repository + dest_path: Destination path in the project + cache_dir: Directory to cache downloaded files + """ + url = f'{BASE_URL}/{source_path}' + + # Create a unique cache filename based on source path + cache_filename = source_path.replace('/', '_') + + # Download file using pooch + file_path = pooch.retrieve( + url=url, + known_hash=None, # Skip hash verification + path=cache_dir, + fname=cache_filename, + ) + + # Create destination directory if it doesn't exist + dest = Path(dest_path) + dest.parent.mkdir(parents=True, exist_ok=True) + + # Copy the file to destination + shutil.copy2(file_path, dest) + print(f'Copied {file_path} -> {dest_path}') + + +def main(): + """Main function to update all documentation assets.""" + print('📥 Updating documentation assets...') + print(f' Repository: {GITHUB_REPO}') + print(f' Branch: {GITHUB_BRANCH}\n') + + # Use a temporary cache directory + cache_dir = Path.home() / '.cache' / GITHUB_REPO + cache_dir.mkdir(parents=True, exist_ok=True) + + # Fetch and copy each asset + for source_path, dest_path in ASSETS_MAP.items(): + try: + fetch_and_copy_asset(source_path, dest_path, cache_dir) + print() + except Exception as e: + print(f'❌ Failed to fetch {source_path}: {e}') + + print('\n✅ Documentation assets updated successfully!') + + +if __name__ == '__main__': + main() diff --git a/tools/update_github_labels.py b/tools/update_github_labels.py new file mode 100644 index 00000000..84de575e --- /dev/null +++ b/tools/update_github_labels.py @@ -0,0 +1,341 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Set/update GitHub labels for current or specified easyscience +repository. + +Requires: + - gh CLI installed + - gh auth login completed + +Usage: + python update_github_labels.py + python update_github_labels.py --dry-run + python update_github_labels.py --repo easyscience/my-repo + python update_github_labels.py --repo easyscience/my-repo --dry-run +""" + +from __future__ import annotations + +import argparse +import json +import shlex +import subprocess # noqa: S404 +import sys +from dataclasses import dataclass + +EASYSCIENCE_ORG = 'easyscience' + + +# Data structures + + +@dataclass(frozen=True) +class Label: + """A GitHub label with name, color, and description.""" + + name: str + color: str + description: str = '' + + +@dataclass(frozen=True) +class LabelRename: + """Mapping from old label name to new label name.""" + + old: str + new: str + + +class Colors: + """Hex color codes for label groups.""" + + SCOPE = 'd73a4a' + MAINTAINER = '0e8a16' + PRIORITY = 'fbca04' + BOT = '5319e7' + + +LABEL_RENAMES = [ + # Default GitHub labels to rename (if they exist) + LabelRename('bug', '[scope] bug'), + LabelRename('documentation', '[scope] documentation'), + LabelRename('duplicate', '[maintainer] duplicate'), + LabelRename('enhancement', '[scope] enhancement'), + LabelRename('good first issue', '[maintainer] good first issue'), + LabelRename('help wanted', '[maintainer] help wanted'), + LabelRename('invalid', '[maintainer] invalid'), + LabelRename('question', '[maintainer] question'), + LabelRename('wontfix', '[maintainer] wontfix'), + # Custom label renames (if they exist) + LabelRename('[bot] pull request', '[bot] release'), +] + +LABELS = [ + # Scope labels + Label( + '[scope] bug', + Colors.SCOPE, + 'Bug report or fix (major.minor.PATCH)', + ), + Label( + '[scope] documentation', + Colors.SCOPE, + 'Documentation only changes (major.minor.patch.POST)', + ), + Label( + '[scope] enhancement', + Colors.SCOPE, + 'Adds/improves features (major.MINOR.patch)', + ), + Label( + '[scope] maintenance', + Colors.SCOPE, + 'Code/tooling cleanup, no feature or bugfix (major.minor.PATCH)', + ), + Label( + '[scope] significant', + Colors.SCOPE, + 'Breaking or major changes (MAJOR.minor.patch)', + ), + Label( + '[scope] ⚠️ label needed', + Colors.SCOPE, + 'Automatically added to issues and PRs without a [scope] label', + ), + # Maintainer labels + Label( + '[maintainer] duplicate', + Colors.MAINTAINER, + 'Already reported or submitted', + ), + Label( + '[maintainer] good first issue', + Colors.MAINTAINER, + 'Good entry-level issue for newcomers', + ), + Label( + '[maintainer] help wanted', + Colors.MAINTAINER, + 'Needs additional help to resolve or implement', + ), + Label( + '[maintainer] invalid', + Colors.MAINTAINER, + 'Invalid, incorrect or outdated', + ), + Label( + '[maintainer] question', + Colors.MAINTAINER, + 'Needs clarification, discussion, or more information', + ), + Label( + '[maintainer] wontfix', + Colors.MAINTAINER, + 'Will not be fixed or continued', + ), + # Priority labels + Label( + '[priority] lowest', + Colors.PRIORITY, + 'Very low urgency', + ), + Label( + '[priority] low', + Colors.PRIORITY, + 'Low importance', + ), + Label( + '[priority] medium', + Colors.PRIORITY, + 'Normal/default priority', + ), + Label( + '[priority] high', + Colors.PRIORITY, + 'Should be prioritized soon', + ), + Label( + '[priority] highest', + Colors.PRIORITY, + 'Urgent. Needs attention ASAP', + ), + Label( + '[priority] ⚠️ label needed', + Colors.PRIORITY, + 'Automatically added to issues without a [priority] label', + ), + # Bot label + Label( + '[bot] release', + Colors.BOT, + 'Automated release PR. Excluded from changelog/versioning', + ), + Label( + '[bot] backmerge', + Colors.BOT, + 'Automated backmerge master → develop failed due to conflicts', + ), +] + + +# Helpers + + +@dataclass(frozen=True) +class CmdResult: + """Result of a shell command execution.""" + + returncode: int + stdout: str + stderr: str + + +def run_cmd( + args: list[str], + *, + dry_run: bool, + check: bool = True, +) -> CmdResult: + """Run a command (or print it in dry-run mode).""" + cmd_str = ' '.join(shlex.quote(a) for a in args) + + if dry_run: + print(f' [dry-run] {cmd_str}') + return CmdResult(0, '', '') + + proc = subprocess.run( + args=args, + text=True, + capture_output=True, + ) + result = CmdResult( + proc.returncode, + proc.stdout.strip(), + proc.stderr.strip(), + ) + + if check and proc.returncode != 0: + raise RuntimeError(f'Command failed ({proc.returncode}): {cmd_str}\n{result.stderr}') + + return result + + +def get_current_repo() -> str: + """Get the current repository name in 'owner/repo' format.""" + result = subprocess.run( + args=[ + 'gh', + 'repo', + 'view', + '--json', + 'nameWithOwner', + ], + text=True, + capture_output=True, + check=True, + ) + data = json.loads(result.stdout) + name_with_owner = data.get('nameWithOwner', '') + + if '/' not in name_with_owner: + raise RuntimeError('Could not determine current repository name') + + return name_with_owner + + +def rename_label( + repo: str, + rename: LabelRename, + *, + dry_run: bool, +) -> None: + """Rename a label, silently skipping if it doesn't exist.""" + result = run_cmd( + args=[ + 'gh', + 'label', + 'edit', + rename.old, + '--name', + rename.new, + '--repo', + repo, + ], + dry_run=dry_run, + check=False, + ) + + if dry_run or result.returncode == 0: + print(f' Rename: {rename.old!r} → {rename.new!r}') + else: + print(f' Skip (not found): {rename.old!r}') + + +def upsert_label( + repo: str, + label: Label, + *, + dry_run: bool, +) -> None: + """Create or update a label.""" + run_cmd( + [ + 'gh', + 'label', + 'create', + label.name, + '--color', + label.color, + '--description', + label.description, + '--force', + '--repo', + repo, + ], + dry_run=dry_run, + ) + print(f' Upsert: {label.name!r}') + + +# Main + + +def main() -> int: + """Entry point: parse arguments and sync labels.""" + parser = argparse.ArgumentParser(description='Sync GitHub labels for easyscience repos') + parser.add_argument( + '--repo', + help='Target repository (owner/name)', + ) + parser.add_argument( + '--dry-run', + action='store_true', + help='Print actions without applying changes', + ) + args = parser.parse_args() + + repo = args.repo or get_current_repo() + org = repo.split('/')[0] + + if org.lower() != EASYSCIENCE_ORG: + print(f"Error: repository '{repo}' is not under '{EASYSCIENCE_ORG}'", file=sys.stderr) + return 2 + + print(f'Repository: {repo}') + if args.dry_run: + print('Mode: DRY-RUN (no changes will be made)\n') + + print('\nRenaming default labels...') + for rename in LABEL_RENAMES: + rename_label(repo, rename, dry_run=args.dry_run) + + print('\nUpserting labels...') + for label in LABELS: + upsert_label(repo, label, dry_run=args.dry_run) + + print('\nDone.') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/vscode-template/settings.json b/vscode-template/settings.json index 35487105..239b6f6a 100644 --- a/vscode-template/settings.json +++ b/vscode-template/settings.json @@ -1,13 +1,11 @@ { - "python.testing.pytestArgs": [ - "tests" - ], - "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true, - "[python]": { - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.organizeImports": "explicit" - }, - }, -} \ No newline at end of file + "python.testing.pytestArgs": ["tests"], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "[python]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + } + } +} From 74e9a5b00e4b785132e8de5f96466cdf35d308cb Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 22 May 2026 08:33:14 +0200 Subject: [PATCH 10/22] prettify the summary (#356) --- .../summary/html_templates.py | 8 +-- src/easyreflectometry/summary/summary.py | 65 +++++++++++++++++-- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/easyreflectometry/summary/html_templates.py b/src/easyreflectometry/summary/html_templates.py index 9b770c01..66012d40 100644 --- a/src/easyreflectometry/summary/html_templates.py +++ b/src/easyreflectometry/summary/html_templates.py @@ -123,10 +123,10 @@ Minimization engine minimization_engine - - - - + + Goodness-of-fit: reduced χ2 + goodness_of_fit + No. of parameters: num_total_params diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index 394c9d78..c03cd3f7 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -1,6 +1,9 @@ # SPDX-FileCopyrightText: 2024 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause +from html import escape +from urllib.parse import quote + import matplotlib.pyplot as plt import numpy as np from easyscience import global_object @@ -16,6 +19,39 @@ from .html_templates import HTML_REFINEMENT_TEMPLATE from .html_templates import HTML_TEMPLATE +_NAME_MAX_LEN = 20 +# Custom href scheme used to pass the full name to QML via TextEdit.hoveredLink. +_TOOLTIP_SCHEME = 'nametooltip' + + +def _format_error(error: float) -> str: + """Format a parameter error the same way the Analysis table does. + + Mirrors the JS ``formatError`` in Fittables.qml: + 2 significant figures; fall back to 1-decimal exponential for long strings. + Zero (no fit run yet) is shown as '0.0'. + """ + if error == 0.0: + return '0.0' + s = f'{error:.2g}' + if len(s) <= 6: + return s + return f'{error:.1e}' + + +def _truncate_name(name: str, max_len: int = _NAME_MAX_LEN) -> str: + """Return an HTML snippet with a truncated name and tooltip for the full text. + + Browsers use the ``title`` attribute; QML reads the ``href`` via + ``TextEdit.hoveredLink`` and shows a native ToolTip. + """ + safe = escape(name) + if len(name) <= max_len: + return safe + short = escape(name[:max_len].rstrip()) + encoded = quote(name, safe='') + return f'{short}…' + class Summary: def __init__(self, project: Project): @@ -140,7 +176,8 @@ def _sample_section(self) -> str: html_parameter = html_parameter.replace('parameter_name', f'{name}') html_parameter = html_parameter.replace('parameter_value', f'{value}') html_parameter = html_parameter.replace('parameter_unit', f'{unit}') - html_parameter = html_parameter.replace('parameter_error', f'{error}') + error_str = _format_error(error) + html_parameter = html_parameter.replace('parameter_error', error_str) html_parameters.append(html_parameter) html_parameters_str = '\n'.join(html_parameters) @@ -162,7 +199,7 @@ def _experiments_section(self) -> str: range_max = max(experiment.y) range_units = 'Å⁻¹' html_experiment = HTML_DATA_COLLECTION_TEMPLATE - html_experiment = html_experiment.replace('experiment_name', f'{experiment_name}') + html_experiment = html_experiment.replace('experiment_name', _truncate_name(experiment_name)) html_experiment = html_experiment.replace('range_min', f'{range_min}') html_experiment = html_experiment.replace('range_max', f'{range_max}') html_experiment = html_experiment.replace('range_units', f'{range_units}') @@ -185,19 +222,37 @@ def _refinement_section(self) -> str: num_free_params = sum(1 for parameter in parameters if parameter.free) num_fixed_params = sum(1 for parameter in parameters if not parameter.free) num_params = num_free_params + num_fixed_params - # goodness_of_fit = self._project.status.goodnessOfFit - # goodness_of_fit = goodness_of_fit.split(' → ')[-1] num_constraints = sum(1 for parameter in parameters if not parameter.independent) + goodness_of_fit = self._compute_goodness_of_fit() + html_refinement = html_refinement.replace('calculation_engine', f'{self._project._calculator.current_interface_name}') html_refinement = html_refinement.replace('minimization_engine', f'{self._project.minimizer.name}') - # html = html.replace('goodness_of_fit', f'{goodness_of_fit}') + html_refinement = html_refinement.replace('goodness_of_fit', goodness_of_fit) html_refinement = html_refinement.replace('num_total_params', f'{num_params}') html_refinement = html_refinement.replace('num_free_params', f'{num_free_params}') html_refinement = html_refinement.replace('num_fixed_params', f'{num_fixed_params}') html_refinement = html_refinement.replace('num_constriants', f'{num_constraints}') return html_refinement + def _compute_goodness_of_fit(self) -> str: + """Return reduced chi² as a formatted string, or 'N/A' if no fit has been run.""" + last_fit_results = getattr(self._project, '_last_fit_results', None) + if not last_fit_results: + return 'N/A' + try: + if len(last_fit_results) == 1: + gof = float(last_fit_results[0].reduced_chi2) + else: + total_chi2 = sum(float(r.chi2) for r in last_fit_results) + total_points = sum(len(r.x) for r in last_fit_results) + n_pars = last_fit_results[0].n_pars + dof = total_points - n_pars + gof = total_chi2 / dof if dof > 0 else 0.0 + return f'{gof:.4g}' + except (AttributeError, TypeError, ValueError, ZeroDivisionError): + return 'N/A' + def _figures_section(self) -> None: """Figures section.""" html_figures = HTML_FIGURES_TEMPLATE From 7e73364306118a75843011be5d0bfab9b23b2503 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 22 May 2026 11:00:23 +0200 Subject: [PATCH 11/22] refactor printout formatter (#358) --- src/easyreflectometry/summary/summary.py | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index c03cd3f7..f53a9392 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -24,19 +24,18 @@ _TOOLTIP_SCHEME = 'nametooltip' -def _format_error(error: float) -> str: - """Format a parameter error the same way the Analysis table does. +def _format_value(value: float, sig_figs: int) -> str: + """Format a numeric value for summary display. - Mirrors the JS ``formatError`` in Fittables.qml: - 2 significant figures; fall back to 1-decimal exponential for long strings. - Zero (no fit run yet) is shown as '0.0'. + *sig_figs* significant figures; fall back to 1-decimal exponential when + the formatted string is too long. Zero is shown as '0.0'. """ - if error == 0.0: + if value == 0.0: return '0.0' - s = f'{error:.2g}' - if len(s) <= 6: + s = f'{value:.{sig_figs}g}' + if len(s) <= sig_figs + 4: return s - return f'{error:.1e}' + return f'{value:.1e}' def _truncate_name(name: str, max_len: int = _NAME_MAX_LEN) -> str: @@ -174,9 +173,9 @@ def _sample_section(self) -> str: html_parameter = HTML_PARAMETER_TEMPLATE html_parameter = html_parameter.replace('parameter_name', f'{name}') - html_parameter = html_parameter.replace('parameter_value', f'{value}') + html_parameter = html_parameter.replace('parameter_value', _format_value(value, 3)) html_parameter = html_parameter.replace('parameter_unit', f'{unit}') - error_str = _format_error(error) + error_str = _format_value(error, 2) html_parameter = html_parameter.replace('parameter_error', error_str) html_parameters.append(html_parameter) @@ -200,8 +199,8 @@ def _experiments_section(self) -> str: range_units = 'Å⁻¹' html_experiment = HTML_DATA_COLLECTION_TEMPLATE html_experiment = html_experiment.replace('experiment_name', _truncate_name(experiment_name)) - html_experiment = html_experiment.replace('range_min', f'{range_min}') - html_experiment = html_experiment.replace('range_max', f'{range_max}') + html_experiment = html_experiment.replace('range_min', _format_value(range_min, 2)) + html_experiment = html_experiment.replace('range_max', _format_value(range_max, 2)) html_experiment = html_experiment.replace('range_units', f'{range_units}') html_experiment = html_experiment.replace('num_data_points', f'{num_data_points}') html_experiment = html_experiment.replace('resolution_function', f'{resolution_function}') From c95d2e00577e46496a634d1ed1118db7624fed0d Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 22 May 2026 11:29:00 +0200 Subject: [PATCH 12/22] make PDF links clickable (#359) --- src/easyreflectometry/summary/summary.py | 42 ++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index f53a9392..c06751af 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -2,6 +2,8 @@ # SPDX-License-Identifier: BSD-3-Clause from html import escape +from importlib.metadata import PackageNotFoundError +from importlib.metadata import version from urllib.parse import quote import matplotlib.pyplot as plt @@ -23,6 +25,36 @@ # Custom href scheme used to pass the full name to QML via TextEdit.hoveredLink. _TOOLTIP_SCHEME = 'nametooltip' +# URLs for known calculation engines and minimizer packages. +_ENGINE_URLS: dict[str, str] = { + 'refnx': 'https://refnx.readthedocs.io', + 'refl1d': 'https://refl1d.readthedocs.io', + 'bornagain': 'https://www.bornagainproject.org', + 'lm': 'https://lmfit.github.io/lmfit-py/', + 'bumps': 'https://bumps.readthedocs.io', + 'dfo': 'https://github.com/fitbenchmarking/dfo-ls', +} + + +def _engine_link(name: str, package: str | None = None) -> str: + """Return an HTML hyperlink for an engine, including its version. + + Falls back to plain text when no URL is known for the engine. + """ + url = _ENGINE_URLS.get(name) or _ENGINE_URLS.get(package or '') + display = escape(name) + if package: + try: + ver = version(package) + except PackageNotFoundError: + ver = None + if ver: + display = f'{display} (v{ver})' + + if url: + return f'{display}' + return display + def _format_value(value: float, sig_figs: int) -> str: """Format a numeric value for summary display. @@ -225,8 +257,14 @@ def _refinement_section(self) -> str: goodness_of_fit = self._compute_goodness_of_fit() - html_refinement = html_refinement.replace('calculation_engine', f'{self._project._calculator.current_interface_name}') - html_refinement = html_refinement.replace('minimization_engine', f'{self._project.minimizer.name}') + html_refinement = html_refinement.replace( + 'calculation_engine', + _engine_link(self._project._calculator.current_interface_name), + ) + html_refinement = html_refinement.replace( + 'minimization_engine', + _engine_link(self._project.minimizer.name, self._project.minimizer.package), + ) html_refinement = html_refinement.replace('goodness_of_fit', goodness_of_fit) html_refinement = html_refinement.replace('num_total_params', f'{num_params}') html_refinement = html_refinement.replace('num_free_params', f'{num_free_params}') From 5642d8c316cd3b5e8203d65a7b2a69e5cc644103 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Thu, 28 May 2026 11:26:41 +0200 Subject: [PATCH 13/22] Move to EasyList (#360) * initial commit * PR review * more tests --- CHANGELOG.md | 33 ++ docs/docs/tutorials/simulation/bilayer.ipynb | 12 +- src/easyreflectometry/model/model.py | 126 ++++--- .../model/model_collection.py | 57 +-- src/easyreflectometry/project.py | 30 +- .../sample/assemblies/base_assembly.py | 26 +- .../sample/assemblies/bilayer.py | 59 +-- .../sample/assemblies/gradient_layer.py | 43 ++- .../sample/assemblies/multilayer.py | 8 +- .../sample/assemblies/repeating_multilayer.py | 21 +- .../sample/assemblies/surfactant_layer.py | 28 +- src/easyreflectometry/sample/base_core.py | 251 +++++++++++-- .../sample/collections/base_collection.py | 351 ++++++++++++++---- .../sample/collections/layer_collection.py | 11 +- .../sample/collections/material_collection.py | 5 +- .../sample/collections/sample.py | 41 +- .../sample/elements/layers/layer.py | 49 ++- .../layers/layer_area_per_molecule.py | 207 +++++------ .../sample/elements/materials/material.py | 37 +- .../elements/materials/material_density.py | 107 ++++-- .../elements/materials/material_mixture.py | 210 ++++++----- .../elements/materials/material_solvated.py | 105 +++--- src/easyreflectometry/summary/summary.py | 4 +- tests/model/test_model.py | 117 ++++++ tests/model/test_model_collection.py | 43 ++- tests/sample/assemblies/test_base_assembly.py | 15 + tests/sample/assemblies/test_bilayer.py | 14 +- .../assemblies/test_surfactant_layer.py | 20 +- .../collections/test_base_collection.py | 179 ++++++++- .../layers/test_layer_area_per_molecule.py | 75 +++- .../materials/test_material_density.py | 19 + .../materials/test_material_mixture.py | 60 ++- .../materials/test_material_solvated.py | 32 +- tests/sample/test_base_core.py | 284 ++++++++++++++ tests/test_project.py | 40 ++ 35 files changed, 2055 insertions(+), 664 deletions(-) create mode 100644 tests/sample/test_base_core.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bb888bf6..2537591f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# Unreleased + +Migrated sample / model classes off the deprecated `easyscience.ObjBase` +and `easyscience.CollectionBase` pipeline. + +- `BaseCore` is now built on `ModelBase`; `BaseCollection` on + `EasyList`. `Model`, `Material`, `Layer`, `MaterialMixture`, + `MaterialSolvated`, `LayerAreaPerMolecule`, `Multilayer`, + `RepeatingMultilayer`, `GradientLayer`, `Bilayer`, `SurfactantLayer`, + `BaseAssembly`, `LayerCollection`, `MaterialCollection`, `Sample`, and + `ModelCollection` were all rewritten to use the new bases. +- Properties returning a `Parameter` (`Material.sld`-style) now expose + the `Parameter` object directly across all sample classes, replacing + the inconsistent legacy behaviour where `MaterialMixture.fraction`, + `MaterialSolvated.solvent_fraction`, + `LayerAreaPerMolecule.area_per_molecule`, and + `LayerAreaPerMolecule.solvent_fraction` returned `float`. Read the + value via `.value` (e.g. `material_mixture.fraction.value`). Setters + still accept a float. `MaterialMixture.sld` / `MaterialMixture.isld` + remain `float` — they are derived via constraints, not constructor + arguments. +- `BaseCollection.remove(index)` (the legacy index-based helper) renamed + to `remove_at(index)`. The standard `MutableSequence.remove(value)` is + now inherited unmodified. +- Project files saved by previous versions cannot be read. + `Project.as_dict` writes `file_format=2`; `Project.from_dict` raises a + clear `ValueError` on missing or unsupported markers. +- `model.get_parameters()` / `collection.get_parameters()` still work + (kept as compatibility shims) but new code should use + `get_all_parameters()`. +- No more `DeprecationWarning` from `easyscience.ObjBase` / + `CollectionBase` on construction of any sample / model object. + # Version 1.6.0 (1 May 2026) Add Mighell-based handling of non-positive-variance points in fitting diff --git a/docs/docs/tutorials/simulation/bilayer.ipynb b/docs/docs/tutorials/simulation/bilayer.ipynb index b16b8284..5f37b010 100644 --- a/docs/docs/tutorials/simulation/bilayer.ipynb +++ b/docs/docs/tutorials/simulation/bilayer.ipynb @@ -202,7 +202,7 @@ "# Access key structural parameters\n", "print(f'Head thickness: {bilayer.front_head_layer.thickness.value:.2f} Å')\n", "print(f'Tail thickness: {bilayer.front_tail_layer.thickness.value:.2f} Å')\n", - "print(f'Area per molecule: {bilayer.front_head_layer.area_per_molecule:.2f} Ų')" + "print(f'Area per molecule: {bilayer.front_head_layer.area_per_molecule.value:.2f} Ų')" ] }, { @@ -224,14 +224,14 @@ "source": [ "# Head layers share thickness and area per molecule via constrain_heads=True,\n", "# but solvent fraction is independent and can be set separately for each side.\n", - "print(f'Front head solvent fraction: {bilayer.front_head_layer.solvent_fraction:.2f}')\n", - "print(f'Back head solvent fraction: {bilayer.back_head_layer.solvent_fraction:.2f}')\n", + "print(f'Front head solvent fraction: {bilayer.front_head_layer.solvent_fraction.value:.2f}')\n", + "print(f'Back head solvent fraction: {bilayer.back_head_layer.solvent_fraction.value:.2f}')\n", "\n", "# We can set them independently\n", "bilayer.back_head_layer.solvent_fraction = 0.5\n", "print('\\nAfter setting back head solvent fraction to 0.5:')\n", - "print(f'Front head solvent fraction: {bilayer.front_head_layer.solvent_fraction:.2f}')\n", - "print(f'Back head solvent fraction: {bilayer.back_head_layer.solvent_fraction:.2f}')" + "print(f'Front head solvent fraction: {bilayer.front_head_layer.solvent_fraction.value:.2f}')\n", + "print(f'Back head solvent fraction: {bilayer.back_head_layer.solvent_fraction.value:.2f}')" ] }, { @@ -685,7 +685,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.12" + "version": "3.12.11" } }, "nbformat": 4, diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index b1aedf85..da1396d0 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -9,15 +9,14 @@ from typing import Union import numpy as np -from easyscience import ObjBase as BaseObj from easyscience import global_object from easyscience.variable import Parameter from easyreflectometry.limits import apply_default_limits from easyreflectometry.sample import BaseAssembly from easyreflectometry.sample import Sample +from easyreflectometry.sample.base_core import BaseCore from easyreflectometry.utils import get_as_parameter -from easyreflectometry.utils import yaml_dump from .resolution_functions import PercentageFwhm from .resolution_functions import ResolutionFunction @@ -58,18 +57,12 @@ ] -class Model(BaseObj): +class Model(BaseCore): """Model is the class that represents the experiment. It is used to store the information about the experiment and to perform the calculations. """ - # Added in super().__init__ - name: str - sample: Sample - scale: Parameter - background: Parameter - def __init__( self, sample: Union[Sample, None] = None, @@ -115,18 +108,45 @@ def __init__( background = get_as_parameter('background', background, DEFAULTS) self.color = color self._is_default = False + self._resolution_function = resolution_function + + super().__init__(name=name, unique_name=unique_name) + self._sample = sample + self._scale = scale + self._background = background + + # Set interface last — propagates to children via BaseCore.generate_bindings + # and then sets the resolution function on the calculator (see setter). + if interface is not None: + self.interface = interface + + # ----- @property accessors for serialization round-trip ----- + + @property + def sample(self) -> Sample: + return self._sample + + @sample.setter + def sample(self, value: Sample) -> None: + self._sample = value - super().__init__( - name=name, - unique_name=unique_name, - sample=sample, - scale=scale, - background=background, - ) - self.resolution_function = resolution_function + @property + def scale(self) -> Parameter: + return self._scale + + @scale.setter + def scale(self, value: float) -> None: + self._scale.value = value + + @property + def background(self) -> Parameter: + return self._background - # Must be set after resolution function - self.interface = interface + @background.setter + def background(self, value: float) -> None: + self._background.value = value + + # ----- assembly management ----- def add_assemblies(self, *assemblies: list[BaseAssembly]) -> None: """Add assemblies to the model sample. @@ -183,15 +203,11 @@ def is_default(self) -> bool: @is_default.setter def is_default(self, value: bool) -> None: - """Set whether this model is a default placeholder. - - Parameters - ---------- - value : bool - True if the model is a default placeholder. - """ + """Set whether this model is a default placeholder.""" self._is_default = value + # ----- resolution function ----- + @property def resolution_function(self) -> ResolutionFunction: """Return the resolution function.""" @@ -204,21 +220,20 @@ def resolution_function(self, resolution_function: ResolutionFunction) -> None: if self.interface is not None: self.interface().set_resolution_function(self._resolution_function) - @property - def interface(self): - """Get the current interface of the object.""" - return self._interface + # ----- interface (override BaseCore's to add resolution-function side effect) ----- - @interface.setter + @BaseCore.interface.setter def interface(self, new_interface) -> None: - """Set the interface for the model.""" - # From super class - self._interface = new_interface + """Set the interface; runs `generate_bindings` and then refreshes the + calculator's resolution function. + """ + # Call BaseCore.interface.setter for the binding propagation. + BaseCore.interface.fset(self, new_interface) if new_interface is not None: - self.generate_bindings() - self._interface().set_resolution_function(self._resolution_function) + new_interface().set_resolution_function(self._resolution_function) + + # ----- representation ----- - # Representation @property def _dict_repr(self) -> dict[str, dict[str, str]]: """A simplified dict representation.""" @@ -238,24 +253,15 @@ def _dict_repr(self) -> dict[str, dict[str, str]]: } } - def __repr__(self) -> str: - """String representation of the layer.""" - return yaml_dump(self._dict_repr) - - def as_dict(self, skip: Optional[list[str]] = None) -> dict: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ + # ----- serialization (custom because resolution_function + interface need special handling) ----- - Parameters - ---------- - skip : Optional[list[str]], optional - List of keys to skip. By default, None. - """ + def to_dict(self, skip: Optional[list[str]] = None) -> dict: + """Serialize the model, encoding the resolution function and interface name.""" if skip is None: skip = [] - skip.extend(['sample', 'resolution_function', 'interface']) - this_dict = super().as_dict(skip=skip) + # Sample/resolution_function/interface get bespoke encoding below. + skip_for_super = list(skip) + ['sample', 'resolution_function', 'interface'] + this_dict = super().to_dict(skip=skip_for_super) this_dict['sample'] = self.sample.as_dict(skip=skip) this_dict['resolution_function'] = self.resolution_function.as_dict(skip=skip) if self.interface is None: @@ -264,23 +270,23 @@ def as_dict(self, skip: Optional[list[str]] = None) -> dict: this_dict['interface'] = self.interface().name return this_dict + def as_dict(self, skip: Optional[list[str]] = None) -> dict: + """Compatibility alias for :meth:`to_dict`.""" + return self.to_dict(skip=skip) + def as_orso(self) -> dict: """Convert the model to a dictionary suitable for ORSO.""" - this_dict = self.as_dict() - - return this_dict + return self.as_dict() @classmethod def from_dict(cls, passed_dict: dict) -> Model: """Create a Model from a dictionary.""" - # Causes circular import if imported at the top + # Circular import if hoisted to module-top. from easyreflectometry.calculators import CalculatorFactory this_dict = copy.deepcopy(passed_dict) - resolution_function = ResolutionFunction.from_dict(this_dict['resolution_function']) - del this_dict['resolution_function'] - interface_name = this_dict['interface'] - del this_dict['interface'] + resolution_function = ResolutionFunction.from_dict(this_dict.pop('resolution_function')) + interface_name = this_dict.pop('interface') if interface_name is not None: interface = CalculatorFactory() interface.switch(interface_name) diff --git a/src/easyreflectometry/model/model_collection.py b/src/easyreflectometry/model/model_collection.py index 1a1b7e88..817fc5f0 100644 --- a/src/easyreflectometry/model/model_collection.py +++ b/src/easyreflectometry/model/model_collection.py @@ -3,7 +3,6 @@ from __future__ import annotations -from typing import List from typing import Optional from typing import Tuple @@ -36,20 +35,33 @@ def __init__( models = DEFAULT_ELEMENTS(interface) else: models = [] - # Needed to ensure an empty list is created when saving and instatiating the object as_dict -> from_dict - # Else collisions might occur in global_object.map - self.populate_if_none = False + + # `_next_color_index` must exist before super().__init__ because each + # `append` during construction routes through `_append_internal` → + # `_advance_color_index`, which reads the attribute. self._next_color_index = next_color_index - super().__init__(name, interface, *models, unique_name=unique_name, **kwargs) + super().__init__( + name, + interface, + *models, + unique_name=unique_name, + populate_if_none=False, + **kwargs, + ) color_count = len(COLORS) if color_count == 0: self._next_color_index = 0 - elif self._next_color_index is None: + elif next_color_index is None: self._next_color_index = len(self) % color_count else: - self._next_color_index %= color_count + self._next_color_index = next_color_index % color_count + + @property + def next_color_index(self) -> Optional[int]: + """Index of the next colour to assign — kept around so it round-trips.""" + return self._next_color_index def add_model(self, model: Optional[Model] = None): """Add a model to the collection. @@ -76,28 +88,24 @@ def duplicate_model(self, index: int): duplicate.name = duplicate.name + ' duplicate' self.append(duplicate) - def as_dict(self, skip: List[str] | None = None) -> dict: - """As dict.""" - this_dict = super().as_dict(skip=skip) - this_dict['populate_if_none'] = self.populate_if_none - this_dict['next_color_index'] = self._next_color_index - return this_dict - @classmethod def from_dict(cls, this_dict: dict) -> ModelCollection: """Create an instance of a collection from a dictionary.""" - collection_dict = this_dict.copy() - # We need to call from_dict on the base class to get the models - dict_data = collection_dict.pop('data') + collection_dict = dict(this_dict) + dict_data = collection_dict.pop('data', []) next_color_index = collection_dict.pop('next_color_index', None) - collection = super().from_dict(collection_dict) # type: ModelCollection + # Reconstruct empty collection via EasyList.from_dict (handles + # protected_types and assigns name/unique_name/populate_if_none). + collection = super().from_dict(collection_dict) + # Append each model without advancing the colour index — the saved + # `next_color_index` below is the source of truth. for model_data in dict_data: collection._append_internal(Model.from_dict(model_data), advance=False) - if len(collection) != len(this_dict['data']): - raise ValueError(f'Expected {len(collection)} models, got {len(this_dict["data"])}') + if len(collection) != len(dict_data): + raise ValueError(f'Expected {len(dict_data)} models, got {len(collection)}') color_count = len(COLORS) if color_count == 0: @@ -115,7 +123,14 @@ def append(self, model: Model) -> None: # type: ignore[override] def _append_internal(self, model: Model, advance: bool) -> None: """Append internal.""" - super().append(model) + # Bypass our own `append` override and go straight to EasyList's + # `MutableSequence.append` → `insert` path. Calling `super().append` + # would dispatch back to `ModelCollection.append` because Python + # resolves `append` via MRO from MutableSequence which doesn't + # define it on a class higher than ModelCollection. + from collections.abc import MutableSequence + + MutableSequence.append(self, model) if advance: self._advance_color_index() diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 5127ad16..5ae272a6 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -90,7 +90,7 @@ def parameters(self) -> List[Parameter]: seen_ids: set[int] = set() if self._models is not None: for model in self._models: - for param in model.get_parameters(): + for param in model.get_all_parameters(): pid = id(param) if pid not in seen_ids: seen_ids.add(pid) @@ -847,9 +847,18 @@ def load_from_json(self, path: Optional[Union[Path, str]] = None): else: print(f'ERROR: File {path} does not exist') + #: Schema version embedded in every serialized project. Bumped from 1 → 2 + #: when the sample/model classes migrated from the legacy + #: ``easyscience.ObjBase``/``CollectionBase`` pipeline to + #: ``ModelBase``/``EasyList``. The on-disk shape of nested objects (Layer, + #: Material, MaterialMixture, MaterialSolvated, LayerAreaPerMolecule, etc.) + #: changed in a way that is not backward-compatible with v1 files. + FILE_FORMAT = 2 + def as_dict(self, include_materials_not_in_model=False): """As dict.""" project_dict = {} + project_dict['file_format'] = self.FILE_FORMAT project_dict['info'] = self._info project_dict['with_experiments'] = self._with_experiments if self._models is not None: @@ -898,6 +907,25 @@ def _as_dict_add_experiments(self, project_dict: dict): def from_dict(self, project_dict: dict): """From dict.""" keys = list(project_dict.keys()) + # Validate file format. v1 files were written by the legacy + # `ObjBase`/`CollectionBase` pipeline; their inner shapes (Layer, + # Material, MaterialMixture, …) are not compatible with the v2 + # `ModelBase`/`EasyList` deserializer. Older files must be re-created. + file_format = project_dict.get('file_format') + if file_format is None: + raise ValueError( + 'This project file predates file_format=2 and cannot be loaded by ' + 'this version of easyreflectometry. The serialization format changed ' + 'when the sample/model classes migrated from the legacy ObjBase / ' + 'CollectionBase pipeline. Please re-create the project from its ' + 'underlying data using the current API.' + ) + if file_format != self.FILE_FORMAT: + raise ValueError( + f'Unsupported project file_format={file_format!r}; this version of ' + f'easyreflectometry only reads file_format={self.FILE_FORMAT}. Please ' + 'either update easyreflectometry or re-create the project.' + ) self._info = project_dict['info'] self._with_experiments = project_dict['with_experiments'] if 'calculator' in keys: diff --git a/src/easyreflectometry/sample/assemblies/base_assembly.py b/src/easyreflectometry/sample/assemblies/base_assembly.py index 39cb2b18..fcb2f06d 100644 --- a/src/easyreflectometry/sample/assemblies/base_assembly.py +++ b/src/easyreflectometry/sample/assemblies/base_assembly.py @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: 2026 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause -from typing import Any from typing import Optional from ..base_core import BaseCore @@ -17,28 +16,33 @@ class BaseAssembly(BaseCore): its index number depends on the number of finite layers in the system, but it might be accessed at index -1. """ - # Added in super().__init__ - #: Name of the assembly. - name: str - #: Layers in the assembly. - layers: LayerCollection - #: Interface to the calculator. - interface: Any - def __init__( self, name: str, type: str, interface, - **layers: LayerCollection, + layers: LayerCollection, + unique_name: Optional[str] = None, ): - super().__init__(name=name, interface=interface, **layers) + super().__init__(name=name, unique_name=unique_name) + self._layers = layers # Type is needed when fitting in easyscience self._type = type self._roughness_constraints_setup = False self._thickness_constraints_setup = False + if interface is not None: + self.interface = interface + + @property + def layers(self) -> LayerCollection: + return self._layers + + @layers.setter + def layers(self, value: LayerCollection) -> None: + self._layers = value + @property def type(self) -> str: """Get type of the assembly. diff --git a/src/easyreflectometry/sample/assemblies/bilayer.py b/src/easyreflectometry/sample/assemblies/bilayer.py index 5409d359..995128ed 100644 --- a/src/easyreflectometry/sample/assemblies/bilayer.py +++ b/src/easyreflectometry/sample/assemblies/bilayer.py @@ -59,6 +59,7 @@ def __init__( front_head_layer: LayerAreaPerMolecule | None = None, front_tail_layer: LayerAreaPerMolecule | None = None, back_head_layer: LayerAreaPerMolecule | None = None, + back_tail_layer: LayerAreaPerMolecule | None = None, name: str = 'EasyBilayer', unique_name: str | None = None, constrain_heads: bool = True, @@ -73,10 +74,16 @@ def __init__( Layer representing the front head part of the bilayer. By default, None. front_tail_layer : LayerAreaPerMolecule | None, optional Layer representing the front tail part of the bilayer. - A back tail layer is created internally with its thickness, area per molecule, - and solvent fraction constrained to match this layer. By default, None. + The back tail layer's thickness, area per molecule, and solvent fraction are + constrained to match this layer. By default, None. back_head_layer : LayerAreaPerMolecule | None, optional Layer representing the back head part of the bilayer. By default, None. + back_tail_layer : LayerAreaPerMolecule | None, optional + Layer representing the back tail part of the bilayer. If omitted, a back tail + is created from the front tail (same molecular_formula, solvent, roughness, etc.). + Independent state (solvent, molecular_formula, name, roughness when + ``conformal_roughness`` is False) is preserved across serialization; the + structural parameters listed above are derived from the front tail. By default, None. name : str, optional Name for bilayer. By default, 'EasyBilayer'. unique_name : str | None, optional @@ -109,13 +116,16 @@ def __init__( interface=interface, ) - # Create back tail layer with initial values copied from the front tail. - # Its parameters will be constrained to the front tail after construction. - back_tail_layer = self._create_back_tail_layer( - front_tail_layer=front_tail_layer, - unique_name=unique_name, - interface=interface, - ) + # If no back tail is supplied, derive one from the front tail. The structural + # parameters (thickness, area_per_molecule, solvent_fraction) get constrained to + # the front tail in `_setup_tail_constraints` below regardless of which path + # produced this layer. + if back_tail_layer is None: + back_tail_layer = self._create_back_tail_layer( + front_tail_layer=front_tail_layer, + unique_name=unique_name, + interface=interface, + ) if back_head_layer is None: back_head_layer = self._create_default_head_layer( @@ -143,7 +153,6 @@ def __init__( interface=interface, ) - self.interface = interface self._conformal_roughness = False self._constrain_heads = False self._tail_constraints_setup = False @@ -271,8 +280,8 @@ def _create_back_tail_layer( molecular_formula=front_tail_layer.molecular_formula, thickness=front_tail_layer.thickness.value, solvent=solvent, - solvent_fraction=front_tail_layer.solvent_fraction, - area_per_molecule=front_tail_layer.area_per_molecule, + solvent_fraction=front_tail_layer.solvent_fraction.value, + area_per_molecule=front_tail_layer.area_per_molecule.value, roughness=front_tail_layer.roughness.value, name=front_tail_layer.name + ' Back', unique_name=unique_name + '_LayerAreaPerMoleculeBackTail', @@ -534,21 +543,17 @@ def _dict_repr(self) -> dict: } } - def as_dict(self, skip: list[str] | None = None) -> dict: - """Produce a cleaned dict using a custom as_dict method. - - The resulting dict matches the parameters in __init__ + def to_dict(self, skip: list[str] | None = None) -> dict: + """Serialize, dropping derived fields. - Parameters - ---------- - skip : list[str] | None, optional - List of keys to skip. By default, None. + The `back_tail_layer` and the underlying `layers` collection are + derived in ``__init__`` from the front head / front tail / back head + constructor arguments, so they are not part of the persisted state. """ - this_dict = super().as_dict(skip=skip) - this_dict['front_head_layer'] = self.front_head_layer.as_dict(skip=skip) - this_dict['front_tail_layer'] = self.front_tail_layer.as_dict(skip=skip) - this_dict['back_head_layer'] = self.back_head_layer.as_dict(skip=skip) - this_dict['constrain_heads'] = self.constrain_heads - this_dict['conformal_roughness'] = self.conformal_roughness - del this_dict['layers'] + this_dict = super().to_dict(skip=skip) + this_dict.pop('layers', None) return this_dict + + def as_dict(self, skip: list[str] | None = None) -> dict: + """Compatibility alias for :meth:`to_dict`.""" + return self.to_dict(skip=skip) diff --git a/src/easyreflectometry/sample/assemblies/gradient_layer.py b/src/easyreflectometry/sample/assemblies/gradient_layer.py index 1e08bb2e..fa38879c 100644 --- a/src/easyreflectometry/sample/assemblies/gradient_layer.py +++ b/src/easyreflectometry/sample/assemblies/gradient_layer.py @@ -53,15 +53,12 @@ def __init__( if front_material is None: front_material = Material(0.0, 0.0, 'Air') - self._front_material = front_material if back_material is None: back_material = Material(6.36, 0.0, 'D2O') - self._back_material = back_material if discretisation_elements < 2: raise ValueError('Discretisation elements must be greater than 2.') - self._discretisation_elements = discretisation_elements gradient_layers = _prepare_gradient_layers( front_material=front_material, @@ -74,9 +71,12 @@ def __init__( layers=gradient_layers, name=name, unique_name=unique_name, - interface=interface, + interface=None, type='Gradient-layer', ) + self._front_material = front_material + self._back_material = back_material + self._discretisation_elements = discretisation_elements self._setup_thickness_constraints() self._enable_thickness_constraints() @@ -87,6 +87,21 @@ def __init__( self.thickness = thickness self.roughness = roughness + if interface is not None: + self.interface = interface + + @property + def front_material(self) -> Material: + return self._front_material + + @property + def back_material(self) -> Material: + return self._back_material + + @property + def discretisation_elements(self) -> int: + return self._discretisation_elements + @property def thickness(self) -> float: """Get the thickness of the gradient layer in Angstrom.""" @@ -129,21 +144,31 @@ def _dict_repr(self) -> dict[str, str]: 'front_layer': self.front_layer._dict_repr, } - def as_dict(self, skip: Optional[list[str]] = None) -> dict: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. + def to_dict(self, skip: Optional[list[str]] = None) -> dict: + """Produces a cleaned dict using a custom to_dict method to skip necessary things. - The resulting dict matches the parameters in __init__ + The resulting dict matches the parameters in __init__: layers are derived + in ``__init__`` from ``front_material``/``back_material``/``discretisation_elements`` + so they are excluded from the serialized representation. Parameters ---------- skip : Optional[list[str]], optional List of keys to skip. By default, None. """ - this_dict = super().as_dict(skip=skip) + this_dict = super().to_dict(skip=skip) # Determined in __init__ - del this_dict['layers'] + this_dict.pop('layers', None) + # `thickness` / `roughness` are read-only float views; the serialized + # constructor args are the floats themselves. + this_dict['thickness'] = float(self.thickness) + this_dict['roughness'] = float(self.roughness) return this_dict + def as_dict(self, skip: Optional[list[str]] = None) -> dict: + """Compatibility alias for :meth:`to_dict`.""" + return self.to_dict(skip=skip) + def _linear_gradient( front_value: float, diff --git a/src/easyreflectometry/sample/assemblies/multilayer.py b/src/easyreflectometry/sample/assemblies/multilayer.py index 9144b3a8..db02592d 100644 --- a/src/easyreflectometry/sample/assemblies/multilayer.py +++ b/src/easyreflectometry/sample/assemblies/multilayer.py @@ -62,7 +62,13 @@ def __init__( # Else collisions might occur in global_object.map self.populate_if_none = False - super().__init__(name, unique_name=unique_name, layers=layers, type=type, interface=interface) + super().__init__( + name=name, + type=type, + interface=interface, + layers=layers, + unique_name=unique_name, + ) def add_layer(self, *layers: tuple[Layer]) -> None: """Add a layer to the multi layer. diff --git a/src/easyreflectometry/sample/assemblies/repeating_multilayer.py b/src/easyreflectometry/sample/assemblies/repeating_multilayer.py index cb396836..79eab4fa 100644 --- a/src/easyreflectometry/sample/assemblies/repeating_multilayer.py +++ b/src/easyreflectometry/sample/assemblies/repeating_multilayer.py @@ -75,9 +75,6 @@ def __init__( layers = LayerCollection(layers, name=layers.name) elif isinstance(layers, list): layers = LayerCollection(*layers, name='/'.join([layer.name for layer in layers])) - # Needed to ensure an empty list is created when saving and instatiating the object as_dict -> from_dict - # Else collisions might occur in global_object.map - self.populate_if_none = False repetitions = get_as_parameter( name='repetitions', @@ -89,11 +86,23 @@ def __init__( super().__init__( layers=layers, name=name, - interface=interface, + unique_name=unique_name, + interface=None, type='Repeating Multi-layer', + populate_if_none=False, ) - self._add_component('repetitions', repetitions) - self.interface = interface + self._repetitions = repetitions + + if interface is not None: + self.interface = interface + + @property + def repetitions(self) -> Parameter: + return self._repetitions + + @repetitions.setter + def repetitions(self, value) -> None: + self._repetitions.value = value # Representation @property diff --git a/src/easyreflectometry/sample/assemblies/surfactant_layer.py b/src/easyreflectometry/sample/assemblies/surfactant_layer.py index 81c9c36c..8e81e097 100644 --- a/src/easyreflectometry/sample/assemblies/surfactant_layer.py +++ b/src/easyreflectometry/sample/assemblies/surfactant_layer.py @@ -57,7 +57,6 @@ def __init__( interface : Calculator interface. By default, None. """ - # We need to generate a unique name to create the nested objects if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) @@ -114,11 +113,13 @@ def __init__( interface=interface, ) - self.interface = interface self.conformal = False + if constrain_area_per_molecule: + self.constrain_area_per_molecule = True if conformal_roughness: self._enable_roughness_constraints() + self.conformal = True @property def tail_layer(self) -> Optional[LayerAreaPerMolecule]: @@ -276,20 +277,13 @@ def _dict_repr(self) -> dict: } } - def as_dict(self, skip: Optional[list[str]] = None) -> dict: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : Optional[list[str]], optional - List of keys to skip. By default, None. + def to_dict(self, skip: Optional[list[str]] = None) -> dict: + """Serialize, dropping the derived ``layers`` field (it is rebuilt + from ``tail_layer`` and ``head_layer`` in ``__init__``). """ - this_dict = super().as_dict(skip=skip) - this_dict['tail_layer'] = self.tail_layer.as_dict(skip=skip) - this_dict['head_layer'] = self.head_layer.as_dict(skip=skip) - this_dict['constrain_area_per_molecule'] = self.constrain_area_per_molecule - this_dict['conformal_roughness'] = self.conformal_roughness - del this_dict['layers'] + this_dict = super().to_dict(skip=skip) + this_dict.pop('layers', None) return this_dict + + def as_dict(self, skip: Optional[list[str]] = None) -> dict: + return self.to_dict(skip=skip) diff --git a/src/easyreflectometry/sample/base_core.py b/src/easyreflectometry/sample/base_core.py index 4cf600a6..611665cd 100644 --- a/src/easyreflectometry/sample/base_core.py +++ b/src/easyreflectometry/sample/base_core.py @@ -1,49 +1,240 @@ # SPDX-FileCopyrightText: 2026 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause +from __future__ import annotations + from abc import abstractmethod +from typing import Any +from typing import Optional -from easyscience import ObjBase as BaseObj +from easyscience.base_classes import ModelBase from easyreflectometry.utils import yaml_dump -class BaseCore(BaseObj): +class BaseCore(ModelBase): + """Local base class for sample-tree objects (Material, Layer, assemblies). + + Built on top of `easyscience.base_classes.ModelBase` (the replacement for + the deprecated `ObjBase`). On top of `ModelBase` this class adds: + + - a `name` property + - an `interface` property whose setter propagates the calculator interface + to child objects and (re)generates bindings + - a yaml-formatted `__repr__` driven by an abstract `_dict_repr` + - an `_get_linkable_attributes` compatibility shim used by the calculator's + `InterfaceFactoryTemplate.generate_bindings` + - an `as_dict` alias for `to_dict` + + Subclass `__init__` convention: + 1. Build child Parameters / sub-objects. + 2. Call ``super().__init__(name=..., unique_name=...)``. + 3. Assign children to backing fields (``self._sld = sld`` etc.) or pass + them as ``**kwargs`` to this base class (transitional path; each + kwarg is stored as a plain instance attribute). + 4. Last: ``self.interface = interface`` (triggers ``generate_bindings``). + """ + def __init__( self, name: str, - interface, - **kwargs, + interface: Any = None, + unique_name: Optional[str] = None, + display_name: Optional[str] = None, + **kwargs: Any, ): - """Init function.""" - super().__init__(name=name, **kwargs) + super().__init__(unique_name=unique_name, display_name=display_name) + self._name = name + self._interface = None + # `user_data` is part of the legacy `BasedBase` API — a free-form dict + # callers stash arbitrary metadata in. Kept for back-compat with code + # like `Project.replace_models_from_orso` which stores the ORSO sample + # name on the model. + self.user_data: dict = {} - # Updates interface using property in base object - self.interface = interface + # Transitional path: subclasses still pass parameter / child objects via + # **kwargs (legacy `ObjBase` accepted them and stashed in `_kwargs`). + # Here we simply store each one as a plain instance attribute so + # `obj.` keeps working. Step 2 of the migration replaces this with + # explicit assignments in each subclass. + for key, value in kwargs.items(): + setattr(self, key, value) - @abstractmethod - def _dict_repr(self) -> dict[str, str]: ... + # Assign interface LAST so children exist when generate_bindings runs. + if interface is not None: + self.interface = interface - def __repr__(self) -> str: - """String representation of the layer. + # ----- name ----- + + @property + def name(self) -> str: + """Common (display-friendly) name.""" + return self._name + + @name.setter + def name(self, value: str) -> None: + self._name = value + + # ----- interface ----- + + @property + def interface(self) -> Any: + """The calculator interface attached to this object (may be None).""" + return self._interface - Returns - ------- - str - A string representation of the layer. + @interface.setter + def interface(self, new_interface: Any) -> None: + self._interface = new_interface + if new_interface is not None: + self.generate_bindings() + + def generate_bindings(self) -> None: + """Propagate the interface to child objects, then bind via the calculator. + + We propagate to any child whose class advertises an ``interface`` property + with a setter. That includes both the new `BaseCore`-based children and + legacy `BasedBase`-derived collections (which extend `SerializerComponent`, + not `NewBase`). """ - return yaml_dump(self._dict_repr) + if self._interface is None: + raise AttributeError('Interface error for generating bindings. `interface` has to be set.') + for attr in self._iter_public_children(): + if self._has_interface_setter(type(attr)): + attr.interface = self._interface + self._interface.generate_bindings(self) + + def _iter_public_children(self): + """Yield public child objects from both class-level (dir) and instance-level (__dict__) attrs. + + `NewBase.__dir__` exposes only class attributes, which means plain instance + attributes (the transitional `setattr(self, key, value)` path in + `__init__`) are invisible to a pure `dir()` scan. To bridge both worlds — + legacy subclasses that still use plain attrs, and migrated subclasses that + expose children via `@property` accessors — this helper unions the two. + Once all subclasses migrate to `@property`-backed children with `_field` + backing storage, the `__dict__` branch becomes a no-op (private names are + skipped). + """ + seen_ids = {id(self)} + # Class-level (properties, methods named like sld/isld/material). + for attr_name in dir(self): + if attr_name.startswith('_') or attr_name in ('interface', 'name'): + continue + try: + attr = getattr(self, attr_name, None) + except AttributeError: + # A subclass @property may legitimately raise AttributeError + # mid-construction (the `_field` backing isn't set yet); skip + # those entries silently. Other exceptions should propagate. + continue + if attr is None or id(attr) in seen_ids: + continue + seen_ids.add(id(attr)) + yield attr + # Instance-level (plain attrs set via the transitional kwargs path). + for attr_name, attr in list(self.__dict__.items()): + if attr_name.startswith('_') or attr_name in ('interface', 'name'): + continue + if attr is None or id(attr) in seen_ids: + continue + seen_ids.add(id(attr)) + yield attr + + @staticmethod + def _has_interface_setter(obj_type: type) -> bool: + for klass in obj_type.__mro__: + prop = klass.__dict__.get('interface') + if isinstance(prop, property): + return prop.fset is not None + return False + + # ----- compatibility shims ----- - # For classes with special serialization needs one must adopt the dict produced by super - # def as_dict(self, skip: list = None) -> dict: - # """Should produce a cleaned dict that matches the parameters in __init__ - # - # :param skip: List of keys to skip, defaults to `None`. - # """ - # if skip is None: - # skip = [] - # this_dict = super().as_dict(skip=skip) - # ... - # Correct the dict here - # ... - # return this_dict + def _get_linkable_attributes(self): + """Used by `easyscience.fitting.calculators.interface_factory.generate_bindings`. + + Returns the same set as :meth:`get_all_variables` (the modern API on + :class:`ModelBase`). Kept under the legacy name because the calculator + in `easyscience` core has not yet been updated. + """ + return self.get_all_variables() + + def get_parameters(self): + """Compatibility shim for legacy callers; prefer :meth:`get_all_parameters`.""" + return self.get_all_parameters() + + def _add_component(self, key: str, component: Any) -> None: + """Compatibility shim for legacy `ObjBase._add_component`. + + Legacy callers (e.g. `LayerAreaPerMolecule`) used this to register an + additional child after `super().__init__`. In the new world the + equivalent is simply setting an attribute; we do that here so the + existing call sites keep working until Step 2 removes them. + """ + setattr(self, key, component) + + def get_all_variables(self): + """Discover Parameters/Descriptors across both class-level and instance-level attrs. + + `ModelBase.get_all_variables` walks `dir(self)`, which `NewBase` restricts + to class attributes only. During the transition some subclasses still + store child Parameters as plain instance attributes (see the kwargs path + in :meth:`__init__`); those are invisible to `dir()`. We therefore also + scan `self.__dict__` for `DescriptorBase` instances and for child + ModelBase objects whose own `get_all_variables` we recurse into. + """ + from easyscience.variable.descriptor_base import DescriptorBase + + out: list = [] + seen_param_ids: set[int] = set() + for attr in self._iter_public_children(): + if isinstance(attr, DescriptorBase): + if id(attr) not in seen_param_ids: + seen_param_ids.add(id(attr)) + out.append(attr) + elif hasattr(attr, 'get_all_variables'): + for v in attr.get_all_variables(): + if id(v) not in seen_param_ids: + seen_param_ids.add(id(v)) + out.append(v) + return out + + def to_dict(self, skip: Optional[list[str]] = None) -> dict[str, Any]: + """Serialize, skipping the calculator interface and unique_name by default. + + The calculator (`CalculatorFactory`) is not serializable and is not part + of the model's persistent state — round-trip code that needs it back + reattaches it after `from_dict`. The legacy `ObjBase`-based pipeline + achieved the same by never including `interface` in its `_kwargs` + encoding; we replicate that here. + + `unique_name` is also stripped by default, matching the legacy + `BasedBase.as_dict` contract. The installed `SerializerBase` does *not* + propagate per-object `_default_unique_name` to nested children — if + we leave it in, child Parameters end up with explicit unique_names in + the dict (e.g. `Parameter_0`) that subsequently collide on reload when + the global counter restarts from 0. + + Pass a *copy* of `skip` to super since `NewBase.to_dict` mutates the + list (appends `unique_name` / `display_name` if those are default). + """ + skip = list(skip or []) + if 'interface' not in skip: + skip.append('interface') + if 'unique_name' not in skip: + skip.append('unique_name') + return super().to_dict(skip=list(skip)) + + def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, Any]: + """Compatibility alias for :meth:`to_dict`.""" + return self.to_dict(skip=skip) + + # ----- repr ----- + + @property + @abstractmethod + def _dict_repr(self) -> dict[str, Any]: ... + + def __repr__(self) -> str: + """Yaml-formatted multi-line string built from :attr:`_dict_repr`.""" + return yaml_dump(self._dict_repr) diff --git a/src/easyreflectometry/sample/collections/base_collection.py b/src/easyreflectometry/sample/collections/base_collection.py index 28d494a5..59f7038e 100644 --- a/src/easyreflectometry/sample/collections/base_collection.py +++ b/src/easyreflectometry/sample/collections/base_collection.py @@ -1,118 +1,331 @@ # SPDX-FileCopyrightText: 2026 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause +from __future__ import annotations + +from typing import Any from typing import List from typing import Optional -from easyscience import global_object -from easyscience.base_classes import CollectionBase as EasyBaseCollection +from easyscience.base_classes import EasyList +from easyscience.base_classes.new_base import NewBase +from easyscience.variable import Parameter from easyreflectometry.utils import yaml_dump -class BaseCollection(EasyBaseCollection): +class BaseCollection(EasyList): + """Local base for sample-tree collections (Material/Layer/Assembly/Model collections). + + Built on top of `easyscience.base_classes.EasyList` (the replacement for + the deprecated `CollectionBase`). On top of `EasyList` this class adds: + + - a `name` property + - an `interface` property whose setter propagates the calculator interface + to every contained item + - propagation of the current `interface` to newly inserted items + - a `populate_if_none` flag preserved for serialization round-trip + - convenience helpers `names`, `move_up`, `move_down`, `remove_at` + - a yaml-formatted `__repr__` driven by `_dict_repr` + - an `as_dict` alias for `to_dict` with `skip=` support and `interface` + excluded by default + + Subclasses (`LayerCollection`, `MaterialCollection`, `Sample`, + `ModelCollection`) keep their existing constructor shape — they pass + `name` and `interface` positionally to this class, items as `*args`, and + additional configuration as kwargs. + """ + def __init__( self, name: str, - interface, - *args, + interface: Any = None, + *args: Any, unique_name: Optional[str] = None, - **kwargs, + populate_if_none: bool = False, + **kwargs: Any, ): - """Init function.""" - if unique_name is None: - unique_name = global_object.generate_unique_name(self.__class__.__name__) + # `_interface` must exist before `super().__init__` because `EasyList` + # calls `self.append(item)` for each positional arg, which routes + # through our `insert` override and reads `self._interface`. + self._interface = None + self._name = name + # Legacy `CollectionBase` accepted items either positionally or as a + # list-valued keyword (e.g. ``LayerCollection(layers=[a, b])``). Pull + # any list-valued kwarg into the positional stream so callers using + # that older pattern keep working. + extra_items = [] + for key in list(kwargs.keys()): + if isinstance(kwargs[key], list) and kwargs[key] and key != 'data': + extra_items.extend(kwargs.pop(key)) + if extra_items: + args = tuple(args) + tuple(extra_items) + super().__init__(*args, unique_name=unique_name, **kwargs) + # `populate_if_none` is a control flag, not state. It is serialized so + # `from_dict` knows whether the original construction filled in + # defaults; the value should be `False` once the data is restored. + self.populate_if_none = populate_if_none - super().__init__(name, unique_name=unique_name, *args, **kwargs) - self.interface = interface + # Assign interface LAST — propagates to all contained items. + if interface is not None: + self.interface = interface - # Needed to ensure an empty list is created when saving and instatiating the object as_dict -> from_dict - # Else collisions might occur in global_object.map - self.populate_if_none = False + # ----- name ----- - def __repr__(self) -> str: - """String representation of the collection. + @property + def name(self) -> str: + return self._name - Returns - ------- - str - A string representation of the collection. - """ - return yaml_dump(self._dict_repr) + @name.setter + def name(self, value: str) -> None: + self._name = value + + # ----- interface ----- @property - def names(self) -> list: - """Names function. + def interface(self) -> Any: + return self._interface + + @interface.setter + def interface(self, new_interface: Any) -> None: + self._interface = new_interface + if new_interface is None: + return + # Propagate to existing items. + for item in self._data: + if self._has_interface_setter(type(item)): + item.interface = new_interface + # Tell the calculator to bind to self (matches the legacy CollectionBase + # behavior which called `interface.generate_bindings(self)` once per + # collection). + if hasattr(new_interface, 'generate_bindings'): + new_interface.generate_bindings(self) + + def _get_key(self, obj): + """Use the item's `name` for string-indexed lookups. - Returns - ------- - s : list - List of names for the elements in the collection. + Matches the legacy `CollectionBase.__getitem__` behaviour which + searched by `item.name`. `EasyList` defaults to `unique_name`; the + existing `Project` code (and callers) look items up by their pretty + name (e.g. `materials['Air']`). """ - return [i.name for i in self] + return getattr(obj, 'name', None) or obj.unique_name - def move_up(self, index: int): - """Move the element at the given index up in the collection. + @staticmethod + def _has_interface_setter(obj_type: type) -> bool: + for klass in obj_type.__mro__: + prop = klass.__dict__.get('interface') + if isinstance(prop, property): + return prop.fset is not None + return False - Parameters - ---------- - index : int - Index of the element to move up. + # ----- mutable-sequence overrides that propagate interface ----- + + def insert(self, index: int, value: Any) -> None: + """Insert and (if an interface is set) propagate it to the new item. + + Legacy `CollectionBase.insert` did `value.interface = self.interface` + after registering the item; we replicate the same behaviour here so + downstream calculator state stays in sync when items are appended + after the collection's interface was already set. + + The type check from `EasyList.insert` is bypassed: each subclass + accepts a single item type (Layer / Material / BaseAssembly / Model) + and enforces it elsewhere, while the EasyList check would require + every item to be a `NewBase` subclass — which was historically not + guaranteed and forces an extra coupling we don't need. """ - if index == 0: + if not isinstance(index, int): + raise TypeError('Index must be an integer') + # Skip the EasyList protected-types check; mimic the rest of its insert + # (duplicate-name warning + append-to-_data). + import warnings as _warnings + + if value in self: + _warnings.warn(f'Item with unique name "{self._get_key(value)}" already in collection, it will be ignored') return - self.insert(index - 1, self.pop(index)) + self._data.insert(index, value) + if self._interface is not None and self._has_interface_setter(type(value)): + value.interface = self._interface - def move_down(self, index: int): - """Move the element at the given index down in the collection. + # ----- helpers ----- - Parameters - ---------- - index : int - Index of the element to move down. + @property + def names(self) -> list: + """List of item names.""" + return [getattr(item, 'name', None) for item in self._data] + + @property + def data(self) -> list: + """Read-only view of the underlying item list. + + Provided for compatibility with code (and tests) written against the + legacy `CollectionBase` shape, which exposed items via `.data`. """ + return list(self._data) + + def move_up(self, index: int) -> None: + """Move the element at the given index up in the collection.""" + if index == 0: + return + self.insert(index - 1, self.pop(index)) + + def move_down(self, index: int) -> None: + """Move the element at the given index down in the collection.""" if index == len(self) - 1: return self.insert(index + 1, self.pop(index)) - def remove(self, index: int): - """Remove an element from the elements. + def remove_at(self, index: int) -> None: + """Remove the item at *index* from the collection. - Parameters - ---------- - index : int - Index of the element to remove. + Renamed from the legacy `BaseCollection.remove(index)` which shadowed + `MutableSequence.remove(value)` (remove-by-value, inherited from + `EasyList`). Callers that meant "remove by index" should use this; the + standard `remove(value)` is still available with its usual semantics. """ self.pop(index) + # ----- compatibility shims (kept until call sites migrate) ----- + + def get_parameters(self) -> List[Parameter]: + """Compatibility alias for legacy callers; prefer `get_all_parameters`.""" + return self.get_all_parameters() + + def get_all_variables(self) -> List: + """Flat list of every Parameter/Descriptor across all items. + + Walks each item in the collection and unions whatever each item + exposes via its own `get_all_variables` (for `ModelBase` / + `BaseCore` children) or, for objects that lack that hook, + unions any direct `DescriptorBase` attributes. + """ + from easyscience.variable.descriptor_base import DescriptorBase + + out: list = [] + seen: set[int] = set() + for item in self._data: + if hasattr(item, 'get_all_variables'): + for v in item.get_all_variables(): + if id(v) not in seen: + seen.add(id(v)) + out.append(v) + elif isinstance(item, DescriptorBase): + if id(item) not in seen: + seen.add(id(item)) + out.append(item) + return out + + def get_all_parameters(self) -> List[Parameter]: + return [v for v in self.get_all_variables() if isinstance(v, Parameter)] + + def get_free_parameters(self) -> List[Parameter]: + return [p for p in self.get_all_parameters() if p.independent and not p.fixed] + + def get_fit_parameters(self) -> List[Parameter]: + """Alias kept for the minimizer; matches `ModelBase.get_fit_parameters`.""" + return self.get_free_parameters() + + def _get_linkable_attributes(self) -> List[Parameter]: + """Bridge for `easyscience.fitting.calculators.interface_factory.generate_bindings`.""" + return self.get_all_variables() + + # ----- repr ----- + @property def _dict_repr(self) -> dict: - """A simplified dict representation. + """A simplified dict representation.""" + return {self.name: [getattr(i, '_dict_repr', repr(i)) for i in self._data]} - Returns - ------- - dict - Simple dictionary. - """ - return {self.name: [i._dict_repr for i in self]} + def __repr__(self) -> str: + try: + return yaml_dump(self._dict_repr) + except Exception: + return super().__repr__() - def as_dict(self, skip: Optional[List[str]] = None) -> dict: - """Create a dictionary representation of the collection. + # ----- serialization ----- - Returns - ------- - dict - A dictionary representation of the collection. + def _convert_to_dict(self, d: dict, encoder=None, skip: Optional[List[str]] = None, **kwargs) -> dict: + """Serializer hook used when this collection is encoded as a *child* + attribute (e.g. `Multilayer.layers`). + + `SerializerBase._convert_to_dict` iterates `_arg_spec` to populate the + base dict and then calls `obj._convert_to_dict(d, ...)` if defined. + Because `data` is supplied via `*args` (VAR_POSITIONAL — not part of + `_arg_spec`), without this hook the nested encoding would miss the + items entirely and round-trip would reconstruct an empty collection. """ if skip is None: skip = [] - this_dict = super().as_dict(skip=skip) - this_dict['data'] = [] - for collection_element in self: - this_dict['data'].append(collection_element.as_dict(skip=skip)) - this_dict['populate_if_none'] = self.populate_if_none - return this_dict + if self._protected_types != [NewBase] and 'protected_types' not in d: + d['protected_types'] = [{'@module': c.__module__, '@class': c.__name__} for c in self._protected_types] + # Encode each item. Defer to the encoder's recursive walk so nested + # ModelBase / NewBase items get properly serialized. + item_skip = list(skip) + items: list = [] + for item in self._data: + if encoder is not None and hasattr(encoder, '_recursive_encoder'): + items.append(encoder._recursive_encoder(item, skip=item_skip, encoder=encoder, full_encode=False)) + elif hasattr(item, 'to_dict'): + try: + items.append(item.to_dict(skip=list(item_skip))) + except TypeError: + items.append(item.to_dict()) + else: + items.append(item) + d['data'] = items + return d + + def to_dict(self, skip: Optional[List[str]] = None) -> dict: + """Serialize with `skip` support; `interface` excluded by default. + + `EasyList.to_dict` doesn't accept a `skip` argument and is hard-wired + to dump `data` plus the parent's `_arg_spec` view. We reimplement here + so existing callers (`Project`, `Model.as_dict`, etc.) can keep + passing `skip=['unique_name']` or similar. + + ``NewBase.to_dict`` mutates the ``skip`` list in-place (e.g. it + appends ``'unique_name'`` when the collection's own unique_name is + default-generated). We therefore pass a *copy* to it, otherwise the + mutation would leak into the per-item serialization below and force + every item Parameter dict to drop its ``unique_name`` — breaking the + from_dict round-trip. + """ + skip = list(skip or []) + if 'interface' not in skip: + skip.append('interface') + # Matches legacy `BasedBase.as_dict`: drop unique_name from the + # serialized form so nested Parameters don't get explicit names that + # would collide with the auto-generated names produced when the global + # counter restarts during reconstruction. + if 'unique_name' not in skip: + skip.append('unique_name') + dict_repr = NewBase.to_dict(self, skip=list(skip)) + if self._protected_types != [NewBase]: + dict_repr['protected_types'] = [{'@module': c.__module__, '@class': c.__name__} for c in self._protected_types] + dict_repr['data'] = [] + for item in self._data: + # Items that are ModelBase / BaseCore subclasses accept `skip`; + # other shapes use their no-arg `to_dict`/`as_dict`. + if hasattr(item, 'to_dict'): + try: + dict_repr['data'].append(item.to_dict(skip=list(skip))) + except TypeError: + dict_repr['data'].append(item.to_dict()) + else: + dict_repr['data'].append(item.as_dict(skip=list(skip))) + return dict_repr + + def as_dict(self, skip: Optional[List[str]] = None) -> dict: + """Compatibility alias for :meth:`to_dict`.""" + return self.to_dict(skip=skip) def __deepcopy__(self, memo): - """Deepcopy function.""" + """Round-trip via dict-skip-unique to get a fresh copy. + + `NewBase.__copy__` already does this; the override is kept (rather + than deleted) to mirror the legacy `BaseCollection.__deepcopy__` + semantics — callers that relied on `copy.deepcopy(collection)` still + get a clone built from `from_dict(as_dict(skip=['unique_name']))`. + """ return self.from_dict(self.as_dict(skip=['unique_name'])) diff --git a/src/easyreflectometry/sample/collections/layer_collection.py b/src/easyreflectometry/sample/collections/layer_collection.py index 99424f72..a3ae0f19 100644 --- a/src/easyreflectometry/sample/collections/layer_collection.py +++ b/src/easyreflectometry/sample/collections/layer_collection.py @@ -15,14 +15,21 @@ def __init__( name: str = 'EasyLayerCollection', interface=None, unique_name: Optional[str] = None, - populate_if_none: bool = True, # Needed to match as_dict signature from BaseCollection + populate_if_none: bool = True, **kwargs, ): """Init function.""" if not layers: layers = [] - super().__init__(name, interface, unique_name=unique_name, *layers, **kwargs) + super().__init__( + name, + interface, + *layers, + unique_name=unique_name, + populate_if_none=populate_if_none, + **kwargs, + ) def add_layer(self, layer: Optional[Layer] = None): """Add a layer to the collection. diff --git a/src/easyreflectometry/sample/collections/material_collection.py b/src/easyreflectometry/sample/collections/material_collection.py index d7b5af3b..726678b2 100644 --- a/src/easyreflectometry/sample/collections/material_collection.py +++ b/src/easyreflectometry/sample/collections/material_collection.py @@ -30,7 +30,7 @@ def __init__( **kwargs, ): """Init function.""" - if not materials: # Empty tuple if no materials are provided + if not materials: if populate_if_none: materials = DEFAULT_ELEMENTS(interface) else: @@ -39,8 +39,9 @@ def __init__( super().__init__( name, interface, - unique_name=unique_name, *materials, + unique_name=unique_name, + populate_if_none=False, **kwargs, ) diff --git a/src/easyreflectometry/sample/collections/sample.py b/src/easyreflectometry/sample/collections/sample.py index 1bbdb156..384626e8 100644 --- a/src/easyreflectometry/sample/collections/sample.py +++ b/src/easyreflectometry/sample/collections/sample.py @@ -52,6 +52,11 @@ def __init__( interface : Calculator interface. By default, None. """ + # `from_dict` (via `EasyList.from_dict`) passes the items as a single + # list-positional arg; unpack that so validation and super() agree. + if len(assemblies) == 1 and isinstance(assemblies[0], list): + assemblies = tuple(assemblies[0]) + if not assemblies: if populate_if_none: assemblies = DEFAULT_ELEMENTS(interface) @@ -61,7 +66,14 @@ def __init__( for assembly in assemblies: if not issubclass(type(assembly), BaseAssembly): raise ValueError('The elements must be an Assembly.') - super().__init__(name, interface, unique_name=unique_name, *assemblies, **kwargs) + super().__init__( + name, + interface, + *assemblies, + unique_name=unique_name, + populate_if_none=populate_if_none, + **kwargs, + ) def add_assembly(self, assembly: Optional[BaseAssembly] = None): """Add an assembly to the sample. @@ -87,13 +99,19 @@ def duplicate_assembly(self, index: int): assembly : Assembly to add. """ + # Order matters: RepeatingMultilayer and SurfactantLayer are subclasses of + # BaseAssembly but not Multilayer; however a RepeatingMultilayer IS a + # Multilayer, so the most-specific check must come first to avoid + # serialising it through the wrong `from_dict`. to_be_duplicated = self[index] - if isinstance(to_be_duplicated, Multilayer): - duplicate = Multilayer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) - elif isinstance(to_be_duplicated, RepeatingMultilayer): + if isinstance(to_be_duplicated, RepeatingMultilayer): duplicate = RepeatingMultilayer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) elif isinstance(to_be_duplicated, SurfactantLayer): duplicate = SurfactantLayer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) + elif isinstance(to_be_duplicated, Multilayer): + duplicate = Multilayer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) + else: + raise TypeError(f'Cannot duplicate assembly of type {type(to_be_duplicated).__name__}') duplicate.name = duplicate.name + ' duplicate' self.append(duplicate) @@ -140,18 +158,3 @@ def subphase(self) -> Layer: return self[-1].front_layer else: return self[-1].back_layer - - # Representation - def as_dict(self, skip: Optional[List[str]] = None) -> dict: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : Optional[List[str]], optional - List of keys to skip. By default, None. - """ - this_dict = super().as_dict(skip=skip) - this_dict['populate_if_none'] = self.populate_if_none - return this_dict diff --git a/src/easyreflectometry/sample/elements/layers/layer.py b/src/easyreflectometry/sample/elements/layers/layer.py index fa58dc15..7eea9872 100644 --- a/src/easyreflectometry/sample/elements/layers/layer.py +++ b/src/easyreflectometry/sample/elements/layers/layer.py @@ -37,14 +37,6 @@ class Layer(BaseCore): - # Added in super().__init__ - #: Material that makes up the layer. - material: Material - #: Thickness of the layer in Angstrom. - thickness: Parameter - #: Roughness of the layer in Angstrom. - roughness: Parameter - def __init__( self, material: Union[Material, None] = None, @@ -95,14 +87,37 @@ def __init__( ) roughness.default_limits_pending = not isinstance(roughness_value, Parameter) - super().__init__( - name=name, - interface=interface, - material=material, - thickness=thickness, - roughness=roughness, - unique_name=unique_name, - ) + super().__init__(name=name, unique_name=unique_name) + self._material = material + self._thickness = thickness + self._roughness = roughness + + if interface is not None: + self.interface = interface + + @property + def material(self) -> Material: + return self._material + + @material.setter + def material(self, value: Material) -> None: + self._material = value + + @property + def thickness(self) -> Parameter: + return self._thickness + + @thickness.setter + def thickness(self, value: float) -> None: + self._thickness.value = value + + @property + def roughness(self) -> Parameter: + return self._roughness + + @roughness.setter + def roughness(self, value: float) -> None: + self._roughness.value = value def assign_material(self, material: Material) -> None: """Assign a material to the layer interface. @@ -112,7 +127,7 @@ def assign_material(self, material: Material) -> None: material : Material The material to assign to the layer. """ - self.material = material + self._material = material if self.interface is not None: self.interface().assign_material_to_layer(self.material.unique_name, self.unique_name) diff --git a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py index 9053aa95..32161dcc 100644 --- a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +++ b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py @@ -55,17 +55,6 @@ class LayerAreaPerMolecule(Layer): molecular formula an area per molecule, and a solvent. """ - # Added in __init__ - #: Real part of the scattering length. - _scattering_length_real: Parameter - #: Imaginary part of the scattering length. - _scattering_length_imag: Parameter - #: Area per molecule in the layer in Anstrom^2. - _area_per_molecule: Parameter - - # Other typer than in __init__.super() - material: MaterialSolvated - def __init__( self, molecular_formula: Union[str, None] = None, @@ -113,7 +102,6 @@ def __init__( interface=interface, ) - # Create the solvated molecule and corresponding constraints if molecular_formula is None: molecular_formula = DEFAULTS['molecular_formula'] molecule_material = Material( @@ -130,40 +118,37 @@ def __init__( default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Thickness', ) - _area_per_molecule = get_as_parameter( + area_per_molecule_param = get_as_parameter( name='area_per_molecule', value=area_per_molecule, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_AreaPerMolecule', ) - _scattering_length_real = get_as_parameter( + scattering_length_real = get_as_parameter( name='scattering_length_real', value=0.0, default_dict=DEFAULTS['sl'], unique_name_prefix=f'{unique_name}_Sl', ) - _scattering_length_imag = get_as_parameter( + scattering_length_imag = get_as_parameter( name='scattering_length_imag', value=0.0, default_dict=DEFAULTS['isl'], unique_name_prefix=f'{unique_name}_Isl', ) - # Constrain the real part of the sld value for the molecule - dependency_expression = 'scattering_length / (thickness * area_per_molecule) * 1e6' - dependency_map = { - 'scattering_length': _scattering_length_real, - 'thickness': thickness, - 'area_per_molecule': _area_per_molecule, - } - molecule_material.sld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) - - # # Constrain the real part of the sld value for the molecule - dependency_expression = 'a / (b*p) * 1e6' - dependency_map = {'a': _scattering_length_real, 'b': thickness, 'p': _area_per_molecule} - molecule_material.sld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) - dependency_map = {'a': _scattering_length_imag, 'b': thickness, 'p': _area_per_molecule} - molecule_material.isld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) + # Constrain molecule.sld / .isld to scattering_length / (thickness * area_per_molecule). + # `_setup_sld_constraints` rebuilds the same expression after from_dict, so keep the + # variable names (`a`, `b`, `p`) consistent with that path. + dependency_expression = 'a / (b*p) * 1e6' + molecule_material.sld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={'a': scattering_length_real, 'b': thickness, 'p': area_per_molecule_param}, + ) + molecule_material.isld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={'a': scattering_length_imag, 'b': thickness, 'p': area_per_molecule_param}, + ) solvated_molecule_material = MaterialSolvated( material=molecule_material, @@ -178,17 +163,85 @@ def __init__( roughness=roughness, name=name, unique_name=unique_name, - interface=interface, + interface=None, ) - self._add_component('_scattering_length_real', _scattering_length_real) - self._add_component('_scattering_length_imag', _scattering_length_imag) - self._add_component('_area_per_molecule', _area_per_molecule) + self._area_per_molecule = area_per_molecule_param + self._scattering_length_real = scattering_length_real + self._scattering_length_imag = scattering_length_imag scattering_length = neutron_scattering_length(molecular_formula) self._scattering_length_real.value = scattering_length.real self._scattering_length_imag.value = scattering_length.imag self._molecular_formula = molecular_formula - self.interface = interface + + if interface is not None: + self.interface = interface + + # ----- constraint plumbing ----- + + def _setup_sld_constraints(self) -> None: + """Wire the inner molecule material's ``sld`` / ``isld`` to depend on + the current scattering-length, thickness, and area-per-molecule + parameters. + + Idempotent — called once from ``__init__`` and again from + ``from_dict`` after the saved Parameter objects replace the + constructor-time temporaries. + """ + molecule_material = self.material.material + for derived in (molecule_material.sld, molecule_material.isld): + if not derived.independent: + derived.make_independent() + + dependency_expression = 'a / (b*p) * 1e6' + molecule_material.sld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={ + 'a': self._scattering_length_real, + 'b': self._thickness, + 'p': self._area_per_molecule, + }, + ) + molecule_material.isld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={ + 'a': self._scattering_length_imag, + 'b': self._thickness, + 'p': self._area_per_molecule, + }, + ) + + # ----- deserialization ----- + + @classmethod + def from_dict(cls, obj_dict: dict) -> 'LayerAreaPerMolecule': + """Re-route the saved ``solvent_fraction`` Parameter and rebuild the + molecule-SLD constraint chain after :class:`ModelBase.from_dict` + swaps in the persisted Parameter objects. + + `ModelBase.from_dict` writes the deserialized ``solvent_fraction`` + Parameter to ``self._solvent_fraction`` (orphan — the live property + delegates to ``self.material.solvent_fraction``, which is + ``self.material._fraction``). It also reassigns ``self._thickness`` + and ``self._area_per_molecule``, but the constraint graph built in + ``__init__`` still references the temporary Parameters created from + the float kwargs. We fix both here. + """ + instance = super().from_dict(obj_dict) + + saved_solvent_fraction = instance.__dict__.pop('_solvent_fraction', None) + if saved_solvent_fraction is not None: + mixture = instance.material + old = mixture._fraction + mixture._fraction = saved_solvent_fraction + try: + instance._global_object.map.prune(old.unique_name) + except (AttributeError, KeyError): + pass + mixture._materials_constraints() + + instance._setup_sld_constraints() + return instance @property def area_per_molecule_parameter(self) -> Parameter: @@ -196,22 +249,15 @@ def area_per_molecule_parameter(self) -> Parameter: return self._area_per_molecule @property - def area_per_molecule(self) -> float: - """Get the area per molecule.""" - return self._area_per_molecule.value + def area_per_molecule(self) -> Parameter: + """The Parameter that controls area per molecule.""" + return self._area_per_molecule @area_per_molecule.setter - def area_per_molecule(self, new_area_per_molecule: float) -> None: - """Set the area per molecule. - - Parameters - ---------- - new_area_per_molecule : float - New area per molecule. - """ - if new_area_per_molecule < 0: - raise ValueError('new_area_per_molecule must be greater than 0.0.') - self._area_per_molecule.value = new_area_per_molecule + def area_per_molecule(self, value: float) -> None: + if value < 0: + raise ValueError('area_per_molecule must be greater than 0.0.') + self._area_per_molecule.value = value @property def molecule(self) -> Material: @@ -225,40 +271,21 @@ def solvent(self) -> Material: @solvent.setter def solvent(self, new_solvent: Material) -> None: - """Set the solvent material. - - Parameters - ---------- - new_solvent : Material - New solvent material. - """ self.material.solvent = new_solvent @property - def solvent_fraction_parameter(self) -> float: + def solvent_fraction_parameter(self) -> Parameter: """Get parameter for the fraction of the layer occupied by the solvent.""" return self.material.solvent_fraction_parameter @property - def solvent_fraction(self) -> float: - """Get the fraction of the layer occupied by the solvent. - - This could be a result of either water solvating the molecule, or incomplete surface coverage of the molecules. - """ + def solvent_fraction(self) -> Parameter: + """The Parameter for the fraction of the layer occupied by the solvent.""" return self.material.solvent_fraction @solvent_fraction.setter - def solvent_fraction(self, solvent_fraction: float) -> None: - """Set the fraction of the layer occupied by the solvent. - - This could be a result of either water solvating the molecule, or incomplete surface coverage of the molecules. - - Parameters - ---------- - solvent_fraction : float - Fraction of layer described by the solvent. - """ - self.material.solvent_fraction = solvent_fraction + def solvent_fraction(self, value: float) -> None: + self.material.solvent_fraction = value @property def molecular_formula(self) -> str: @@ -267,16 +294,8 @@ def molecular_formula(self) -> str: @molecular_formula.setter def molecular_formula(self, formula_string: str) -> None: - """Set the formula of the molecule in the material. - - Parameters - ---------- - formula_string : str - String that defines the molecular formula. - """ self._molecular_formula = formula_string scattering_length = neutron_scattering_length(formula_string) - # The molecule is also being updated through the constraints self._scattering_length_real.value = scattering_length.real self._scattering_length_imag.value = scattering_length.imag @@ -285,30 +304,8 @@ def molecular_formula(self, formula_string: str) -> None: @property def _dict_repr(self) -> dict[str, str]: - """Dictionary representation of the `area_per_molecule` object. - - Produces a simple dictionary. - """ + """Dictionary representation of the `area_per_molecule` object.""" dict_repr = super()._dict_repr dict_repr['molecular_formula'] = self._molecular_formula - dict_repr['area_per_molecule'] = f'{self.area_per_molecule:.2f} {self._area_per_molecule.unit}' + dict_repr['area_per_molecule'] = f'{self._area_per_molecule.value:.2f} {self._area_per_molecule.unit}' return dict_repr - - def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : Optional[list[str]], optional - List of keys to skip. By default, None. - """ - this_dict = super().as_dict(skip=skip) - this_dict['solvent_fraction'] = self.material._fraction.as_dict(skip=skip) - this_dict['area_per_molecule'] = self._area_per_molecule.as_dict(skip=skip) - this_dict['solvent'] = self.solvent.as_dict(skip=skip) - del this_dict['material'] - del this_dict['_scattering_length_real'] - del this_dict['_scattering_length_imag'] - return this_dict diff --git a/src/easyreflectometry/sample/elements/materials/material.py b/src/easyreflectometry/sample/elements/materials/material.py index 42091bd6..f072a639 100644 --- a/src/easyreflectometry/sample/elements/materials/material.py +++ b/src/easyreflectometry/sample/elements/materials/material.py @@ -37,10 +37,6 @@ class Material(BaseCore): - # Added in super().__init__ - sld: Parameter - isld: Parameter - def __init__( self, sld: Union[Parameter, float, None] = None, @@ -83,13 +79,28 @@ def __init__( ) apply_default_limits(isld, 'isld') - super().__init__( - name=name, - sld=sld, - isld=isld, - interface=interface, - unique_name=unique_name, - ) + super().__init__(name=name, unique_name=unique_name) + self._sld = sld + self._isld = isld + + if interface is not None: + self.interface = interface + + @property + def sld(self) -> Parameter: + return self._sld + + @sld.setter + def sld(self, value: float) -> None: + self._sld.value = value + + @property + def isld(self) -> Parameter: + return self._isld + + @isld.setter + def isld(self, value: float) -> None: + self._isld.value = value # Representation @property @@ -97,7 +108,7 @@ def _dict_repr(self) -> dict[str, str]: """A simplified dict representation.""" return { self.name: { - 'sld': f'{self.sld.value:.3f}e-6 {self.sld.unit}', - 'isld': f'{self.isld.value:.3f}e-6 {self.isld.unit}', + 'sld': f'{self._sld.value:.3f}e-6 {self._sld.unit}', + 'isld': f'{self._isld.value:.3f}e-6 {self._isld.unit}', } } diff --git a/src/easyreflectometry/sample/elements/materials/material_density.py b/src/easyreflectometry/sample/elements/materials/material_density.py index b85bda98..5be1cf9d 100644 --- a/src/easyreflectometry/sample/elements/materials/material_density.py +++ b/src/easyreflectometry/sample/elements/materials/material_density.py @@ -41,12 +41,6 @@ class MaterialDensity(Material): - # Added in __init__ - scattering_length_real: Parameter - scattering_length_imag: Parameter - molecular_weight: Parameter - density: Parameter - def __init__( self, chemical_structure: Union[str, None] = None, @@ -123,14 +117,59 @@ def __init__( dependency_map = {'d': density, 'sl': scattering_length_imag, 'mw': mw} isld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) - super().__init__(sld, isld, name=name, interface=interface) + super().__init__(sld=sld, isld=isld, name=name, unique_name=unique_name, interface=None) - self._add_component('scattering_length_real', scattering_length_real) - self._add_component('scattering_length_imag', scattering_length_imag) - self._add_component('molecular_weight', mw) - self._add_component('density', density) + self._scattering_length_real = scattering_length_real + self._scattering_length_imag = scattering_length_imag + self._molecular_weight = mw + self._density = density self._chemical_structure = chemical_structure - self.interface = interface + + if interface is not None: + self.interface = interface + + def _setup_sld_constraints(self) -> None: + """Wire the derived `sld` / `isld` to depend on the current density and + scattering-length Parameters. + + Idempotent — invoked once from `__init__` and again from `from_dict` + after :class:`ModelBase` has swapped in the saved Parameter objects. + """ + for derived in (self._sld, self._isld): + if not derived.independent: + derived.make_independent() + + dependency_expression = '1e-23*(0.602214076e6 * d * sl) / mw' + self._sld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={ + 'd': self._density, + 'sl': self._scattering_length_real, + 'mw': self._molecular_weight, + }, + ) + self._isld.make_dependent_on( + dependency_expression=dependency_expression, + dependency_map={ + 'd': self._density, + 'sl': self._scattering_length_imag, + 'mw': self._molecular_weight, + }, + ) + + @classmethod + def from_dict(cls, obj_dict: dict) -> 'MaterialDensity': + """Re-attach sld/isld dependencies after deserialization. + + :class:`ModelBase.from_dict` re-points `self._density` at the + deserialized Parameter (because `density` is a constructor argument); + the constraint graph built in `__init__` still references the + temporary Parameter created from the float kwarg. Rebuild here so + `q.density = X` propagates to the derived SLDs. + """ + instance = super().from_dict(obj_dict) + instance._setup_sld_constraints() + return instance @property def chemical_structure(self) -> str: @@ -148,8 +187,28 @@ def chemical_structure(self, structure_string: str) -> None: """ self._chemical_structure = structure_string scattering_length = neutron_scattering_length(structure_string) - self.scattering_length_real.value = scattering_length.real - self.scattering_length_imag.value = scattering_length.imag + self._scattering_length_real.value = scattering_length.real + self._scattering_length_imag.value = scattering_length.imag + + @property + def density(self) -> Parameter: + return self._density + + @density.setter + def density(self, value: float) -> None: + self._density.value = value + + @property + def molecular_weight(self) -> Parameter: + return self._molecular_weight + + @property + def scattering_length_real(self) -> Parameter: + return self._scattering_length_real + + @property + def scattering_length_imag(self) -> Parameter: + return self._scattering_length_imag @property def _dict_repr(self) -> dict[str, str]: @@ -158,23 +217,3 @@ def _dict_repr(self) -> dict[str, str]: mat_dict['chemical_structure'] = self._chemical_structure mat_dict['density'] = f'{self.density.value:.2e} {self.density.unit}' return mat_dict - - def as_dict(self, skip: list = []) -> dict[str, str]: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : list, optional - List of keys to skip. By default, []. - """ - this_dict = super().as_dict(skip=skip) - # From Material - del this_dict['sld'] - del this_dict['isld'] - # Determined in __init__ - del this_dict['scattering_length_real'] - del this_dict['scattering_length_imag'] - del this_dict['molecular_weight'] - return this_dict diff --git a/src/easyreflectometry/sample/elements/materials/material_mixture.py b/src/easyreflectometry/sample/elements/materials/material_mixture.py index c999093e..1ab76ddc 100644 --- a/src/easyreflectometry/sample/elements/materials/material_mixture.py +++ b/src/easyreflectometry/sample/elements/materials/material_mixture.py @@ -28,11 +28,6 @@ class MaterialMixture(BaseCore): - # Added in super().__init__ - _material_a: Material - _material_b: Material - _fraction: Parameter - def __init__( self, material_a: Union[Material, None] = None, @@ -74,108 +69,57 @@ def __init__( unique_name_prefix=f'{unique_name}_Fraction', ) - sld = weighted_average( + sld_value = weighted_average( a=material_a.sld.value, b=material_b.sld.value, p=fraction.value, ) - isld = weighted_average( + isld_value = weighted_average( a=material_a.isld.value, b=material_b.isld.value, p=fraction.value, ) - self._sld = get_as_parameter( + sld = get_as_parameter( name='sld', - value=sld, + value=sld_value, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Sld', ) - self._isld = get_as_parameter( + isld = get_as_parameter( name='isld', - value=isld, + value=isld_value, default_dict=DEFAULTS, unique_name_prefix=f'{unique_name}_Isld', ) - # To avoid problems when setting the interface - # self._sld and self._isld need to be declared before calling the super constructor - super().__init__( - name, - _material_a=material_a, - _material_b=material_b, - _fraction=fraction, - interface=interface, - ) + # `name` may be None to signal "derive from material names"; resolve + # before super().__init__ since BaseCore stores `_name` directly. if name is None: - self._update_name() - - self._materials_constraints() - self.interface = interface - - def _get_linkable_attributes(self): - """Get linkable attributes.""" - return [self._sld, self._isld] - - @property - def sld(self) -> float: - """Sld function.""" - return self._sld.value - - @property - def isld(self) -> float: - """Isld function.""" - return self._isld.value - - def _materials_constraints(self): - """Materials constraints.""" - dependency_expression = 'a * (1 - p) + b * p' - dependency_map = { - 'a': self._material_a.sld, - 'b': self._material_b.sld, - 'p': self._fraction, - } - self._sld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) + resolved_name = material_a.name + '/' + material_b.name + else: + resolved_name = name - dependency_map = { - 'a': self._material_a.isld, - 'b': self._material_b.isld, - 'p': self._fraction, - } - self._isld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) + super().__init__(name=resolved_name, unique_name=unique_name) + self._material_a = material_a + self._material_b = material_b + self._fraction = fraction + self._sld = sld + self._isld = isld - @property - def fraction(self) -> float: - """Get the fraction of material_b.""" - return self._fraction.value + self._materials_constraints() - @fraction.setter - def fraction(self, fraction: float) -> None: - """Setter for fraction of material_b. + if interface is not None: + self.interface = interface - Parameters - ---------- - fraction : float - The fraction of material_b in material_a. - """ - if not isinstance(fraction, float): - raise ValueError('fraction must be a float') - self._fraction.value = fraction + # ----- constructor-arg accessors ----- @property def material_a(self) -> Material: - """Getter for material_a.""" return self._material_a @material_a.setter def material_a(self, new_material_a: Material) -> None: - """Setter for material_a. - - Parameters - ---------- - new_material_a : Material - New Material for material_a. - """ self._material_a = new_material_a self._materials_constraints() if self.interface is not None: @@ -184,28 +128,108 @@ def material_a(self, new_material_a: Material) -> None: @property def material_b(self) -> Material: - """Getter for material_b.""" return self._material_b @material_b.setter def material_b(self, new_material_b: Material) -> None: - """Setter for material_b. - - Parameters - ---------- - new_material_b : Material - New Materialfor material_b. - """ self._material_b = new_material_b self._materials_constraints() if self.interface is not None: self.interface.generate_bindings(self) self._update_name() + @property + def fraction(self) -> Parameter: + """The Parameter that controls the mixing fraction of material_b in material_a.""" + return self._fraction + + @fraction.setter + def fraction(self, value: float) -> None: + if not isinstance(value, (int, float)): + raise ValueError('fraction must be a float') + self._fraction.value = value + + # ----- derived sld / isld parameters (shared shape with Material) ----- + # + # These are *derived* via the constraints set up in `_materials_constraints` + # (not constructor arguments) so we expose them as floats to match the + # legacy MaterialMixture API. The underlying Parameter objects remain + # available as `self._sld` / `self._isld`. + + @property + def sld(self) -> float: + return self._sld.value + + @property + def isld(self) -> float: + return self._isld.value + + # ----- calculator binding ----- + + def _get_linkable_attributes(self): + """Return the *mixed* sld / isld parameters for calculator binding. + + Override of the inherited `BaseCore._get_linkable_attributes`, which + walks `get_all_variables()` and would otherwise expose the **child** + materials' sld/isld (because our own `sld` / `isld` are floats, not + Parameters). The calculator's `InterfaceFactoryTemplate.generate_bindings` + matches by parameter `name`; without this override it binds to + `material_a.sld` and reflectivity is computed off the wrong SLD. + """ + return [self._sld, self._isld] + + # ----- internal helpers ----- + + def _materials_constraints(self): + """Wire the mixed `_sld` / `_isld` to depend on the current child + material parameters and the current `_fraction`. Idempotent: callers + invoke this once from ``__init__`` and again from ``from_dict`` after + the saved Parameters have been reattached (so the dependency graph + points at the right objects, not the temporary constructor params).""" + # Detach any existing dependency before rebuilding so make_dependent_on + # doesn't chain on top of stale references. + for derived in (self._sld, self._isld): + if not derived.independent: + derived.make_independent() + + dependency_expression = 'a * (1 - p) + b * p' + dependency_map = { + 'a': self._material_a.sld, + 'b': self._material_b.sld, + 'p': self._fraction, + } + self._sld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) + + dependency_map = { + 'a': self._material_a.isld, + 'b': self._material_b.isld, + 'p': self._fraction, + } + self._isld.make_dependent_on(dependency_expression=dependency_expression, dependency_map=dependency_map) + def _update_name(self) -> None: """Update name.""" self.name = self._material_a.name + '/' + self._material_b.name + # ----- deserialization ----- + + @classmethod + def from_dict(cls, obj_dict: dict) -> 'MaterialMixture': + """Re-attach mixed-sld dependencies after :class:`ModelBase` swaps in + the saved ``_fraction`` Parameter. + + :class:`ModelBase.from_dict` runs ``__init__`` (which builds the + ``_sld`` / ``_isld`` constraints against the *temporary* ``_fraction`` + created from the float kwargs) and then re-points ``self._fraction`` + at the persisted Parameter. The constraint graph still references the + temporary object, so subsequent ``mm.fraction = X`` mutations don't + propagate to ``_sld`` / ``_isld``. Re-running ``_materials_constraints`` + here points the graph at the live objects. + """ + instance = super().from_dict(obj_dict) + instance._materials_constraints() + return instance + # Representation @property def _dict_repr(self) -> dict[str, str]: @@ -219,19 +243,3 @@ def _dict_repr(self) -> dict[str, str]: 'material_b': self._material_b._dict_repr, } } - - def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : Optional[list[str]], optional - List of keys to skip. By default, None. - """ - this_dict = super().as_dict(skip=skip) - this_dict['material_a'] = self._material_a.as_dict(skip=skip) - this_dict['material_b'] = self._material_b.as_dict(skip=skip) - this_dict['fraction'] = self._fraction.as_dict(skip=skip) - return this_dict diff --git a/src/easyreflectometry/sample/elements/materials/material_solvated.py b/src/easyreflectometry/sample/elements/materials/material_solvated.py index 454904ba..d6121d10 100644 --- a/src/easyreflectometry/sample/elements/materials/material_solvated.py +++ b/src/easyreflectometry/sample/elements/materials/material_solvated.py @@ -72,6 +72,7 @@ def __init__( material_b=solvent, fraction=solvent_fraction, name=name, + unique_name=unique_name, interface=interface, ) if name is None: @@ -84,13 +85,7 @@ def material(self) -> Material: @material.setter def material(self, new_material: Material) -> None: - """Set the material. - - Parameters - ---------- - new_material : Material - Matrerial to be useed. - """ + """Set the material.""" self.material_a = new_material @property @@ -100,13 +95,7 @@ def solvent(self) -> Material: @solvent.setter def solvent(self, new_solvent: Material) -> None: - """Set the solvent. - - Parameters - ---------- - new_solvent : Material - Solvent to be used. - """ + """Set the solvent.""" self.material_b = new_solvent @property @@ -115,39 +104,58 @@ def solvent_fraction_parameter(self) -> Parameter: return self._fraction @property - def solvent_fraction(self) -> float: - """Get the fraction of layer described by the solvent. + def solvent_fraction(self) -> Parameter: + """The Parameter for the fraction of the layer described by the solvent. - This might be fraction of: - Solvation where solvent is within the layer - Patches of solvent in the layer where no material is present. + This might be the fraction of: + - solvation where solvent is within the layer, or + - patches of solvent in the layer where no material is present. """ - return self.fraction + return self._fraction @solvent_fraction.setter def solvent_fraction(self, solvent_fraction: float) -> None: - """Set the fraction of layer covered by the material. - - This might be fraction of: - Solvation where solvent is within the layer - Patches of solvent in the layer where no material is present. - - Parameters - ---------- - solvent_fraction : float - Fraction of layer described by the solvent. - """ - try: - self.fraction = solvent_fraction - if solvent_fraction < 0 or solvent_fraction > 1: - raise ValueError('solvent_fraction must be between 0 and 1') - except ValueError: + """Set the fraction of layer covered by the material.""" + if not isinstance(solvent_fraction, (int, float)): raise ValueError('solvent_fraction must be a float between 0 and 1') + if solvent_fraction < 0 or solvent_fraction > 1: + raise ValueError('solvent_fraction must be between 0 and 1') + self._fraction.value = solvent_fraction def _update_name(self) -> None: """Update name.""" self.name = self._material_a.name + ' in ' + self._material_b.name + # ----- deserialization ----- + + @classmethod + def from_dict(cls, obj_dict: dict) -> 'MaterialSolvated': + """Re-route the saved ``solvent_fraction`` Parameter onto ``_fraction``. + + :class:`ModelBase.from_dict` writes the saved Parameter to + ``_solvent_fraction`` because that's the constructor-arg name, but + the live `solvent_fraction` property returns ``self._fraction`` + (the field MaterialMixture maintains). Without this override the + saved fit metadata (fixed/bounds/etc.) is stranded on the unused + ``_solvent_fraction`` attribute and the active parameter keeps the + defaults from `__init__`. + + Also re-runs `_materials_constraints` so the parent MaterialMixture's + mixed `_sld` / `_isld` depend on the live `_fraction`, not the + temporary Parameter created from the float kwarg. + """ + instance = super().from_dict(obj_dict) + saved = instance.__dict__.pop('_solvent_fraction', None) + if saved is not None: + old = instance._fraction + instance._fraction = saved + try: + instance._global_object.map.prune(old.unique_name) + except (AttributeError, KeyError): + pass + instance._materials_constraints() + return instance + # Representation @property def _dict_repr(self) -> dict[str, str]: @@ -161,28 +169,3 @@ def _dict_repr(self) -> dict[str, str]: 'solvent': self.solvent._dict_repr, } } - - def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, str]: - """Produces a cleaned dict using a custom as_dict method to skip necessary things. - - The resulting dict matches the parameters in __init__ - - Parameters - ---------- - skip : Optional[list[str]], optional - List of keys to skip. By default, None. - """ - this_dict = super().as_dict(skip=skip) - this_dict['material'] = self.material.as_dict(skip=skip) - this_dict['solvent'] = self.solvent.as_dict(skip=skip) - this_dict['solvent_fraction'] = self._fraction.as_dict(skip=skip) - # Property and protected varible from material_mixture - del this_dict['material_a'] - del this_dict['_material_a'] - # Property and protected varible from material_mixture - del this_dict['material_b'] - del this_dict['_material_b'] - # Property and protected varible from material_mixture - del this_dict['fraction'] - del this_dict['_fraction'] - return this_dict diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index c06751af..2fc2846f 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -191,7 +191,7 @@ def _sample_section(self) -> str: # Get parameters directly from the model instead of using project.parameters model = self._project._models[self._project.current_model_index] - parameters = model.get_parameters() + parameters = model.get_all_parameters() for parameter in parameters: path = global_object.map.find_path(model.unique_name, parameter.unique_name) @@ -248,7 +248,7 @@ def _refinement_section(self) -> str: # Get parameters directly from the model model = self._project._models[self._project.current_model_index] - parameters = model.get_parameters() + parameters = model.get_all_parameters() num_free_params = sum(1 for parameter in parameters if parameter.free) num_fixed_params = sum(1 for parameter in parameters if not parameter.free) diff --git a/tests/model/test_model.py b/tests/model/test_model.py index 2d623512..b11149c1 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -430,3 +430,120 @@ def test_dict_round_trip(interface): model.interface().reflectity_profile([0.3], model.unique_name), model_from_dict.interface().reflectity_profile([0.3], model_from_dict.unique_name), ) + + +class TestModelPropertyAccessors: + """Tests for the new @property accessors introduced in the ModelBase/EasyList migration.""" + + def test_scale_setter_updates_value(self): + model = Model() + model.scale = 3.0 + assert model.scale.value == 3.0 + + def test_scale_getter_returns_parameter(self): + model = Model(scale=2.5) + from easyscience.variable import Parameter + + assert isinstance(model.scale, Parameter) + assert model.scale.value == 2.5 + + def test_background_setter_updates_value(self): + model = Model() + model.background = 1e-6 + assert model.background.value == 1e-6 + + def test_background_getter_returns_parameter(self): + model = Model(background=5e-6) + from easyscience.variable import Parameter + + assert isinstance(model.background, Parameter) + assert model.background.value == 5e-6 + + def test_sample_setter(self): + model = Model() + new_sample = Sample(name='NewSample') + model.sample = new_sample + assert model.sample.name == 'NewSample' + + def test_to_dict_includes_sample_and_resolution(self): + model = Model() + d = model.to_dict() + assert 'sample' in d + assert 'resolution_function' in d + assert 'interface' in d # interface is None, encoded as None + assert 'name' in d + + def test_to_dict_with_interface_name(self): + interface = CalculatorFactory() + model = Model(interface=interface) + d = model.to_dict() + assert d['interface'] == 'refnx' + + def test_to_dict_excludes_derived_fields(self): + model = Model() + d = model.to_dict() + # sample, resolution_function, interface are handled separately + assert 'sample' in d + # The super().to_dict() skip prevents these from being top-level + assert 'resolution_function' in d + assert 'interface' in d + + def test_as_dict_alias(self): + model = Model() + assert model.as_dict() == model.to_dict() + + def test_is_default_property(self): + model = Model() + assert model.is_default is False + model.is_default = True + assert model.is_default is True + + +class TestModelRoundTrip: + """Tests verifying serialization round-trip for the Model class.""" + + def test_basic_round_trip_preserves_name(self): + global_object.map._clear() + model = Model(name='MyModel') + d = model.as_dict() + global_object.map._clear() + restored = Model.from_dict(d) + assert restored.name == 'MyModel' + + def test_round_trip_preserves_scale_and_background(self): + global_object.map._clear() + model = Model(scale=2.0, background=1e-7) + d = model.as_dict() + global_object.map._clear() + restored = Model.from_dict(d) + assert restored.scale.value == 2.0 + assert restored.background.value == 1e-7 + + def test_round_trip_preserves_resolution_function(self): + global_object.map._clear() + model = Model(resolution_function=PercentageFwhm(3.0)) + d = model.as_dict() + global_object.map._clear() + restored = Model.from_dict(d) + assert restored._resolution_function.smearing(100) == 3.0 + + def test_round_trip_preserves_interface(self): + global_object.map._clear() + interface = CalculatorFactory() + model = Model(interface=interface) + d = model.as_dict() + global_object.map._clear() + restored = Model.from_dict(d) + assert restored.interface().name == 'refnx' + + def test_round_trip_preserves_is_default(self): + global_object.map._clear() + model = Model() + model.is_default = True + d = model.as_dict() + global_object.map._clear() + restored = Model.from_dict(d) + # Note: is_default is a runtime flag that may not survive round-trip + # because from_dict reconstructs via __init__ which resets _is_default. + # This test documents the current behaviour. + assert restored.is_default is False diff --git a/tests/model/test_model_collection.py b/tests/model/test_model_collection.py index 4a6fd521..dda554b1 100644 --- a/tests/model/test_model_collection.py +++ b/tests/model/test_model_collection.py @@ -65,7 +65,7 @@ def test_add_model_color_cycle(self): collection.add_model() assert collection[1].color == COLORS[1] - collection.remove(0) + collection.remove_at(0) collection.add_model() assert collection[0].color == COLORS[1] @@ -101,7 +101,7 @@ def test_delete_model(self): # Then collection = ModelCollection(model_1, model_2) - collection.remove(0) + collection.remove_at(0) # Expect assert len(collection) == 1 @@ -163,3 +163,42 @@ def test_legacy_from_dict_sets_color_index(self): restored.add_model() assert [model.color for model in restored] == [COLORS[0], COLORS[1]] + + def test_next_color_index_property(self): + """next_color_index should be accessible as a property for serialization.""" + collection = ModelCollection(populate_if_none=False) + collection.add_model() + idx = collection.next_color_index + assert isinstance(idx, int) + assert idx >= 0 + + def test_next_color_index_none_when_no_colors(self): + """When COLORS is empty, next_color_index returns 0.""" + # We can test the None case when COLORS has entries, it wraps + collection = ModelCollection(populate_if_none=False) + # Without adding models, the index should still be accessible + assert collection.next_color_index is not None + + def test_from_dict_preserves_data_count(self): + """from_dict should reconstruct the exact number of models.""" + global_object.map._clear() + model_1 = Model(name='M1') + model_2 = Model(name='M2') + p = ModelCollection(model_1, model_2) + d = p.as_dict() + global_object.map._clear() + q = ModelCollection.from_dict(d) + assert len(q) == 2 + + def test_from_dict_with_extra_data_entries(self): + """from_dict should handle data entries correctly.""" + global_object.map._clear() + model_1 = Model(name='M1') + model_2 = Model(name='M2') + p = ModelCollection(model_1, model_2) + d = p.as_dict() + global_object.map._clear() + q = ModelCollection.from_dict(d) + assert len(q) == 2 + assert q[0].name == 'M1' + assert q[1].name == 'M2' diff --git a/tests/sample/assemblies/test_base_assembly.py b/tests/sample/assemblies/test_base_assembly.py index 482cf669..84228eca 100644 --- a/tests/sample/assemblies/test_base_assembly.py +++ b/tests/sample/assemblies/test_base_assembly.py @@ -182,3 +182,18 @@ def test_set_back_layer_with_front(self, base_assembly: BaseAssembly) -> None: # Expect assert base_assembly.layers == [self.mock_layer_0, self.mock_layer_1] + + def test_layers_setter(self) -> None: + """The layers property setter should replace the layer list.""" + global_object.map._clear() + BaseAssembly.__abstractmethods__ = set() + assembly = BaseAssembly( + name='test', + type='type', + interface=MagicMock(), + layers=[MagicMock(), MagicMock()], + ) + new_layers = [MagicMock(), MagicMock(), MagicMock()] + assembly.layers = new_layers + assert assembly.layers == new_layers + assert len(assembly.layers) == 3 diff --git a/tests/sample/assemblies/test_bilayer.py b/tests/sample/assemblies/test_bilayer.py index 03949ee7..431ad866 100644 --- a/tests/sample/assemblies/test_bilayer.py +++ b/tests/sample/assemblies/test_bilayer.py @@ -119,7 +119,7 @@ def test_tail_layers_linked(self): # Initial values should match assert p.front_tail_layer.thickness.value == p.back_tail_layer.thickness.value - assert p.front_tail_layer.area_per_molecule == p.back_tail_layer.area_per_molecule + assert p.front_tail_layer.area_per_molecule.value == p.back_tail_layer.area_per_molecule.value # Change front tail thickness - back tail should follow p.front_tail_layer.thickness.value = 20.0 @@ -128,8 +128,8 @@ def test_tail_layers_linked(self): # Change front tail area per molecule - back tail should follow p.front_tail_layer.area_per_molecule = 55.0 - assert p.front_tail_layer.area_per_molecule == 55.0 - assert p.back_tail_layer.area_per_molecule == 55.0 + assert p.front_tail_layer.area_per_molecule.value == 55.0 + assert p.back_tail_layer.area_per_molecule.value == 55.0 def test_constrain_heads_enabled(self): """Test head thickness/area constraint when enabled.""" @@ -142,8 +142,8 @@ def test_constrain_heads_enabled(self): # Change front head area per molecule - back head should follow p.front_head_layer.area_per_molecule = 60.0 - assert p.front_head_layer.area_per_molecule == 60.0 - assert p.back_head_layer.area_per_molecule == 60.0 + assert p.front_head_layer.area_per_molecule.value == 60.0 + assert p.back_head_layer.area_per_molecule.value == 60.0 def test_constrain_heads_disabled(self): """Test heads are independent when constraint disabled.""" @@ -190,8 +190,8 @@ def test_head_hydration_independent(self): p.back_head_layer.solvent_fraction = 0.5 # They should remain independent - assert p.front_head_layer.solvent_fraction == 0.3 - assert p.back_head_layer.solvent_fraction == 0.5 + assert p.front_head_layer.solvent_fraction.value == 0.3 + assert p.back_head_layer.solvent_fraction.value == 0.5 def test_conformal_roughness_enabled(self): """Test all roughnesses are linked when conformal roughness enabled.""" diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index 62b92689..653b19ba 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -41,31 +41,31 @@ def test_from_pars(self): assert p.tail_layer.molecular_formula == 'C8O10H12P' assert p.tail_layer.thickness.value == 12 assert p.tail_layer.solvent.as_dict() == h2o.as_dict() - assert p.tail_layer.solvent_fraction == 0.5 - assert p.tail_layer.area_per_molecule == 50 + assert p.tail_layer.solvent_fraction.value == 0.5 + assert p.tail_layer.area_per_molecule.value == 50 assert p.tail_layer.roughness.value == 2 assert p.layers[1].name == 'A Test Head Layer' assert p.head_layer.name == 'A Test Head Layer' assert p.head_layer.molecular_formula == 'C10H24' assert p.head_layer.thickness.value == 10 assert p.head_layer.solvent.as_dict() == noth2o.as_dict() - assert p.head_layer.solvent_fraction == 0.2 - assert p.head_layer.area_per_molecule == 40 + assert p.head_layer.solvent_fraction.value == 0.2 + assert p.head_layer.area_per_molecule.value == 40 assert p.name == 'A Test' def test_constraint_area_per_molecule(self): p = SurfactantLayer() p.tail_layer._area_per_molecule.value = 30 - assert p.tail_layer.area_per_molecule == 30.0 - assert p.head_layer.area_per_molecule == 48.2 + assert p.tail_layer.area_per_molecule.value == 30.0 + assert p.head_layer.area_per_molecule.value == 48.2 assert p.constrain_area_per_molecule is False p.constrain_area_per_molecule = True - assert p.tail_layer.area_per_molecule == 30 - assert p.head_layer.area_per_molecule == 30 + assert p.tail_layer.area_per_molecule.value == 30 + assert p.head_layer.area_per_molecule.value == 30 assert p.constrain_area_per_molecule is True p.tail_layer._area_per_molecule.value = 40 - assert p.tail_layer.area_per_molecule == 40 - assert p.head_layer.area_per_molecule == 40 + assert p.tail_layer.area_per_molecule.value == 40 + assert p.head_layer.area_per_molecule.value == 40 def test_conformal_roughness(self): p = SurfactantLayer() diff --git a/tests/sample/collections/test_base_collection.py b/tests/sample/collections/test_base_collection.py index 44b8e208..c3036bc9 100644 --- a/tests/sample/collections/test_base_collection.py +++ b/tests/sample/collections/test_base_collection.py @@ -3,6 +3,8 @@ from unittest.mock import MagicMock +import pytest + from easyreflectometry.sample.collections.base_collection import BaseCollection from easyreflectometry.sample.elements.layers.layer import Layer @@ -160,10 +162,185 @@ def test_remove(self): p.append(Layer(name='layer_4')) # Then - p.remove(1) + p.remove_at(1) # Then assert len(p) == 3 assert p[0].name == 'layer_1' assert p[1].name == 'layer_3' assert p[2].name == 'layer_4' + + # ---- new BaseCollection (EasyList-based) specific tests ---- + + def test_name_getter_and_setter(self): + """name property should be readable and writable.""" + p = BaseCollection('original', MagicMock()) + assert p.name == 'original' + p.name = 'changed' + assert p.name == 'changed' + + def test_data_property(self): + """data property should return a read-only copy of the internal list.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + data = p.data + assert len(data) == 1 + assert data[0].name == 'layer' + # Mutating the returned copy must not affect the collection + data.append(Layer(name='extra')) + assert len(p) == 1 + + def test_interface_propagates_to_existing_items(self): + """Setting interface after construction should propagate to all items.""" + mock_iface = MagicMock() + elem = Layer(name='layer') + # Pass interface=None explicitly and items as positional args + p = BaseCollection('name', None, elem) + assert p.interface is None + p.interface = mock_iface + # The interface setter propagates to items then calls generate_bindings on the mock + assert elem.interface is mock_iface + mock_iface.generate_bindings.assert_called() + + def test_interface_propagates_to_inserted_items(self): + """Items inserted after interface is set should receive the interface.""" + mock_iface = MagicMock() + p = BaseCollection('name', mock_iface) + elem = Layer(name='new_layer') + p.append(elem) + assert elem.interface is mock_iface + + def test_get_all_variables(self): + """get_all_variables should collect parameters from all items.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + variables = p.get_all_variables() + # A Layer has thickness, roughness, and the material's sld/isld + names = {v.name for v in variables if hasattr(v, 'name')} + assert 'thickness' in names + assert 'roughness' in names + + def test_get_all_parameters(self): + """get_all_parameters should filter to only Parameter instances.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + params = p.get_all_parameters() + for param in params: + assert param.__class__.__name__ == 'Parameter' + + def test_get_free_parameters(self): + """get_free_parameters should return only independent, non-fixed parameters.""" + elem = Layer(name='layer') + # By default thickness/roughness are fixed + p = BaseCollection('name', MagicMock(), elem) + free = p.get_free_parameters() + # By default all params are fixed, so empty + assert len(free) == 0 + # Unfix one + elem.thickness.fixed = False + free = p.get_free_parameters() + assert len(free) == 1 + assert free[0].name == 'thickness' + + def test_get_fit_parameters_alias(self): + """get_fit_parameters should be an alias for get_free_parameters.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + assert p.get_fit_parameters() == p.get_free_parameters() + + def test_get_parameters_shim(self): + """get_parameters should be a compatibility alias for get_all_parameters.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + assert p.get_parameters() == p.get_all_parameters() + + def test_get_linkable_attributes(self): + """_get_linkable_attributes should return get_all_variables.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + assert p._get_linkable_attributes() == p.get_all_variables() + + def test_to_dict_includes_data_and_name(self): + """to_dict should serialize data items and collection metadata.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + d = p.to_dict() + assert d['name'] == 'name' + assert len(d['data']) == 1 + assert d['data'][0]['name'] == 'layer' + + def test_to_dict_skips_interface(self): + """to_dict should exclude the interface field.""" + mock_iface = MagicMock() + p = BaseCollection('name', mock_iface) + d = p.to_dict() + assert 'interface' not in d + + def test_to_dict_skips_unique_name_by_default(self): + """to_dict should drop unique_name (matching legacy behaviour).""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + d = p.to_dict() + assert 'unique_name' not in d + + def test_as_dict_is_alias_for_to_dict(self): + """as_dict should delegate to to_dict.""" + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + assert p.as_dict() == p.to_dict() + + def test_deepcopy_round_trips(self): + """__deepcopy__ should produce an equivalent collection via from_dict.""" + import copy + + elem = Layer(name='layer') + # Use a concrete subclass (LayerCollection) that properly supports deepcopy + from easyreflectometry.sample.collections.layer_collection import LayerCollection + + p = LayerCollection(elem, name='test_layers') + p_copy = copy.deepcopy(p) + assert len(p_copy) == len(p) + assert p_copy[0].name == p[0].name + + def test_repr_handles_exception_gracefully(self): + """__repr__ should not crash even with items lacking _dict_repr.""" + mock_item = MagicMock() + # Deliberately make _dict_repr raise + del mock_item._dict_repr + p = BaseCollection('name', interface=None) + # Manually insert the mock item bypassing normal insert + p._data.append(mock_item) + # Should not raise + result = repr(p) + assert isinstance(result, str) + + def test_insert_rejects_non_integer_index(self): + """insert should raise TypeError for non-integer indices.""" + p = BaseCollection('name', interface=None) + with pytest.raises(TypeError, match='Index must be an integer'): + p.insert('not_an_int', Layer(name='x')) + + def test_duplicate_insert_is_warned(self): + """Inserting an already-present item should warn and skip.""" + import warnings + + elem = Layer(name='layer') + p = BaseCollection('name', MagicMock(), elem) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + p.append(elem) + assert len(w) == 1 + assert 'already in collection' in str(w[0].message) + # Length unchanged + assert len(p) == 1 + + def test_get_key_uses_name(self): + """_get_key should use the item's name property.""" + elem = Layer(name='mylayer') + p = BaseCollection('name', MagicMock(), elem) + assert p._get_key(elem) == 'mylayer' + + def test_has_interface_setter(self): + """_has_interface_setter should correctly detect interface-writable types.""" + assert BaseCollection._has_interface_setter(Layer) is True + assert BaseCollection._has_interface_setter(int) is False diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index 4d0abf7d..0d466be7 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -18,7 +18,7 @@ class TestLayerAreaPerMolecule(unittest.TestCase): def test_default(self): p = LayerAreaPerMolecule() assert p.molecular_formula == 'C10H18NO8P' - assert p.area_per_molecule == 48.2 + assert p.area_per_molecule.value == 48.2 assert str(p._area_per_molecule.unit) == 'Å^2' assert p._area_per_molecule.fixed is True assert p.thickness.value == 10.0 @@ -33,7 +33,7 @@ def test_default(self): assert p.solvent.sld.value == 6.36 assert p.solvent.isld.value == 0 assert p.solvent.name == 'D2O' - assert p.solvent_fraction == 0.2 + assert p.solvent_fraction.value == 0.2 assert str(p.material._fraction.unit) == 'dimensionless' assert p.material._fraction.fixed is True @@ -49,12 +49,12 @@ def test_from_pars(self): name='PG/H2O', ) assert p.molecular_formula == 'C8O10H12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 def test_from_pars_constraint(self): h2o = Material(-0.561, 0, 'H2O') @@ -68,15 +68,15 @@ def test_from_pars_constraint(self): name='PG/H2O', ) assert p.molecular_formula == 'C8O10H12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 p.area_per_molecule = 30 - assert p.area_per_molecule == 30 + assert p.area_per_molecule.value == 30 assert_almost_equal(p.material.sld, 0.7119138888888887) p.thickness.value = 10 assert p.thickness.value == 10 @@ -95,24 +95,24 @@ def test_solvent_change(self): name='PG/H2O', ) assert p.molecular_formula == 'C8O10H12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 print(p.material) assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 d2o = Material(6.335, 0, 'D2O') p.solvent = d2o assert p.molecular_formula == 'C8O10H12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 assert_almost_equal(p.material.sld, 3.762948333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == 6.335 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 def test_molecular_formula_change(self): h2o = Material(-0.561, 0, 'H2O') @@ -126,24 +126,24 @@ def test_molecular_formula_change(self): name='PG/H2O', ) assert p.molecular_formula == 'C8O10H12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 assert p.material.name == 'C8O10H12P in H2O' p.molecular_formula = 'C8O10D12P' assert p.molecular_formula == 'C8O10D12P' - assert p.area_per_molecule == 50 + assert p.area_per_molecule.value == 50 assert_almost_equal(p.material.sld, 1.3558483333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 assert p.solvent.isld.value == 0 - assert p.solvent_fraction == 0.5 + assert p.solvent_fraction.value == 0.5 assert p.material.name == 'C8O10D12P in H2O' def test_dict_repr(self): @@ -185,3 +185,48 @@ def test_dict_round_trip(self): # Expect assert sorted(p.as_dict()) == sorted(q.as_dict()) + + def test_solvent_fraction_metadata_and_mutation_after_round_trip(self): + """Regression covering two bugs at once: + + - ``solvent_fraction`` is a constructor argument but its backing + storage is ``self.material._fraction`` (delegated through + ``MaterialSolvated``). Without an override, ``ModelBase.from_dict`` + would put the saved Parameter on an orphan ``_solvent_fraction`` + attribute and reset the live one to constructor defaults. + - ``__init__`` builds the molecule SLD constraint against the + *temporary* thickness / area_per_molecule Parameters; after + ``from_dict`` reattaches the saved ones, mutating them must still + propagate to ``material.material.sld``. + """ + p = LayerAreaPerMolecule( + molecular_formula='C10H18NO8P', + thickness=12.0, + solvent_fraction=0.3, + area_per_molecule=50.0, + roughness=2.0, + ) + p.solvent_fraction.fixed = False + p.solvent_fraction.min = 0.12 + + original_mol_sld = p.material.material.sld.value + p_dict = p.as_dict() + global_object.map._clear() + + q = LayerAreaPerMolecule.from_dict(p_dict) + + # solvent_fraction metadata preserved, no orphan field. + assert q.solvent_fraction.value == 0.3 + assert q.solvent_fraction.fixed is False + assert q.solvent_fraction.min == 0.12 + assert '_solvent_fraction' not in q.__dict__ + + # Molecule SLD constraint preserved. + assert_almost_equal(q.material.material.sld.value, original_mol_sld) + + # Mutate the independent parameters and verify the constraint chain + # propagates to the derived molecule SLD. + q.area_per_molecule = 25.0 # half APM doubles SLD + assert_almost_equal(q.material.material.sld.value, 2 * original_mol_sld) + q.thickness.value = 6.0 # half thickness doubles SLD again + assert_almost_equal(q.material.material.sld.value, 4 * original_mol_sld) diff --git a/tests/sample/elements/materials/test_material_density.py b/tests/sample/elements/materials/test_material_density.py index 99c6615a..0b424cad 100644 --- a/tests/sample/elements/materials/test_material_density.py +++ b/tests/sample/elements/materials/test_material_density.py @@ -64,3 +64,22 @@ def test_dict_round_trip(self): q = MaterialDensity.from_dict(p_dict) assert sorted(p.as_dict()) == sorted(q.as_dict()) + + def test_density_mutation_propagates_after_round_trip(self): + """Regression: after ``from_dict`` reattaches the saved ``_density`` + Parameter, mutating it must propagate to ``sld`` / ``isld`` (which + are constrained off it). The ``__init__``-time constraint references + the temporary constructor Parameter; ``from_dict`` rebuilds the + graph so subsequent mutations propagate correctly. + """ + p = MaterialDensity(chemical_structure='Si', density=2.33) + original_sld = p.sld.value + p_dict = p.as_dict() + global_object.map._clear() + + q = MaterialDensity.from_dict(p_dict) + assert_almost_equal(q.sld.value, original_sld) + + q.density = 4.66 + # SLD scales linearly with density (constraint: d * sl / mw, etc.) + assert_almost_equal(q.sld.value, 2 * original_sld) diff --git a/tests/sample/elements/materials/test_material_mixture.py b/tests/sample/elements/materials/test_material_mixture.py index 0e70a2b7..3c2a3f65 100644 --- a/tests/sample/elements/materials/test_material_mixture.py +++ b/tests/sample/elements/materials/test_material_mixture.py @@ -13,7 +13,7 @@ class TestMaterialMixture: def test_default(self) -> None: material_mixture = MaterialMixture() - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.186) assert_almost_equal(material_mixture.isld, 0) @@ -22,7 +22,7 @@ def test_default(self) -> None: def test_default_constraint(self) -> None: material_mixture = MaterialMixture() - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.186) assert_almost_equal(material_mixture.isld, 0) @@ -37,57 +37,57 @@ def test_fraction_constraint(self): p = Material() q = Material(6.908, -0.278, 'Boron') material_mixture = MaterialMixture(p, q, 0.2) - assert material_mixture.fraction == 0.2 + assert material_mixture.fraction.value == 0.2 assert_almost_equal(material_mixture.sld, 4.7304) assert_almost_equal(material_mixture.isld, -0.0556) material_mixture._fraction.value = 0.5 - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert_almost_equal(material_mixture.sld, 5.54700) assert_almost_equal(material_mixture.isld, -0.1390) def test_material_a_change(self) -> None: material_mixture = MaterialMixture() - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.186) assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_a = q - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 5.54700) assert_almost_equal(material_mixture.isld, -0.1390) def test_material_b_change(self) -> None: material_mixture = MaterialMixture() - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.186) assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 5.54700) assert_almost_equal(material_mixture.isld, -0.1390) def test_material_b_change_double(self) -> None: material_mixture = MaterialMixture() - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.186) assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q assert material_mixture.name == 'EasyMaterial/Boron' - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 5.54700) assert_almost_equal(material_mixture.isld, -0.1390) r = Material(0.00, 0.00, 'ACMW') material_mixture.material_b = r assert material_mixture.name == 'EasyMaterial/ACMW' - assert material_mixture.fraction == 0.5 + assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 2.0930) assert_almost_equal(material_mixture.isld, 0.0000) @@ -96,7 +96,7 @@ def test_from_pars(self): p = Material() q = Material(6.908, -0.278, 'Boron') material_mixture = MaterialMixture(p, q, 0.2) - assert material_mixture.fraction == 0.2 + assert material_mixture.fraction.value == 0.2 assert str(material_mixture._fraction.unit) == 'dimensionless' assert_almost_equal(material_mixture.sld, 4.7304) assert_almost_equal(material_mixture.isld, -0.0556) @@ -142,3 +142,39 @@ def test_update_name(self) -> None: # Expect assert material_mixture.name == 'name_a/name_b' + + def test_calculator_binding_uses_mixed_sld(self) -> None: + """Regression: the calculator wrapper must bind to the mixture's own + ``_sld``/``_isld`` (the weighted average), not to either child material's + sld/isld parameter. Without an explicit ``_get_linkable_attributes`` + override the inherited dir-walk picks up the first matching child + parameter and the wrapper silently gets the wrong SLD. + """ + from easyreflectometry.calculators import CalculatorFactory + + interface = CalculatorFactory() + material_a = Material(sld=2.0, isld=0.0) + material_b = Material(sld=6.0, isld=0.0) + mixture = MaterialMixture(material_a, material_b, fraction=0.25, interface=interface) + + # 2 * 0.75 + 6 * 0.25 = 1.5 + 1.5 = 3.0 + assert_almost_equal(mixture.sld, 3.0) + wrapper_material = interface()._wrapper.storage['material'][mixture.unique_name] + assert_almost_equal(wrapper_material.real.value, 3.0) + assert_almost_equal(wrapper_material.imag.value, 0.0) + + def test_mutation_propagates_after_round_trip(self) -> None: + """Regression: after ``from_dict`` swaps in the saved ``_fraction`` + Parameter, the dependency graph for ``_sld``/``_isld`` must point at + the live ``_fraction`` (not the temp Parameter created from the + float kwarg in ``__init__``).""" + p = MaterialMixture(Material(sld=2.0), Material(sld=6.0), fraction=0.25) + p_dict = p.as_dict() + global_object.map._clear() + + q = MaterialMixture.from_dict(p_dict) + assert_almost_equal(q.sld, 3.0) + + q.fraction = 0.8 + # 2 * 0.2 + 6 * 0.8 = 0.4 + 4.8 = 5.2 + assert_almost_equal(q.sld, 5.2) diff --git a/tests/sample/elements/materials/test_material_solvated.py b/tests/sample/elements/materials/test_material_solvated.py index 3d4a9917..3af8e379 100644 --- a/tests/sample/elements/materials/test_material_solvated.py +++ b/tests/sample/elements/materials/test_material_solvated.py @@ -32,7 +32,7 @@ def test_init(self, material_solvated: MaterialSolvated) -> None: # When Then Expect assert material_solvated.material_a == self.material assert material_solvated.material_b == self.solvent - assert material_solvated.fraction == 0.1 + assert material_solvated.fraction.value == 0.1 assert material_solvated.name == 'name' assert material_solvated.interface == self.mock_interface self.mock_interface.generate_bindings.call_count == 2 @@ -69,14 +69,14 @@ def test_set_solvent(self, material_solvated: MaterialSolvated) -> None: def test_solvent_fraction(self, material_solvated: MaterialSolvated) -> None: # When Then Expect - assert material_solvated.solvent_fraction == 0.1 + assert material_solvated.solvent_fraction.value == 0.1 def test_set_solvent_fraction(self, material_solvated: MaterialSolvated) -> None: # When Then material_solvated.solvent_fraction = 1.0 # Expect - assert material_solvated.solvent_fraction == 1.0 + assert material_solvated.solvent_fraction.value == 1.0 def test_set_solvent_fraction_exception(self, material_solvated: MaterialSolvated) -> None: # When Then Expect @@ -133,3 +133,29 @@ def test_update_name(self, material_solvated: MaterialSolvated) -> None: # Expect assert material_solvated.name == 'name_a in name_b' + + def test_solvent_fraction_metadata_survives_round_trip(self) -> None: + """Regression: ``solvent_fraction`` is a constructor argument, but its + backing storage is ``_fraction`` (inherited from MaterialMixture). + ``ModelBase.from_dict`` would write the saved Parameter to + ``_solvent_fraction`` (an orphan), silently resetting the active + parameter to constructor defaults. We re-route to ``_fraction`` in + ``MaterialSolvated.from_dict``. + """ + material = Material(sld=6.36, isld=0, name='D2O') + solvent = Material(sld=-0.561, isld=0, name='H2O') + p = MaterialSolvated(material=material, solvent=solvent, solvent_fraction=0.3) + # Tweak fit metadata that the default would not have. + p.solvent_fraction.fixed = False + p.solvent_fraction.min = 0.12 + + p_dict = p.as_dict() + global_object.map._clear() + + q = MaterialSolvated.from_dict(p_dict) + + assert q.solvent_fraction.value == 0.3 + assert q.solvent_fraction.fixed is False + assert q.solvent_fraction.min == 0.12 + # No orphan field. + assert '_solvent_fraction' not in q.__dict__ diff --git a/tests/sample/test_base_core.py b/tests/sample/test_base_core.py new file mode 100644 index 00000000..e9b32df7 --- /dev/null +++ b/tests/sample/test_base_core.py @@ -0,0 +1,284 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +"""Tests for BaseCore class — the new ModelBase-based foundation for sample-tree objects.""" + +from __future__ import annotations + +from unittest.mock import MagicMock + +import pytest +from easyscience import global_object +from easyscience.variable import Parameter + +from easyreflectometry.sample.base_core import BaseCore + +# --------------------------------------------------------------------------- +# Minimal concrete subclass for testing the abstract BaseCore +# --------------------------------------------------------------------------- + + +class _ConcreteCore(BaseCore): + """A non-abstract BaseCore that exposes a simple ``_dict_repr``.""" + + def __init__(self, name='TestCore', interface=None, unique_name=None, **kwargs): + super().__init__(name=name, interface=interface, unique_name=unique_name, **kwargs) + + @property + def _dict_repr(self) -> dict[str, str]: + return {self.name: {'type': 'concrete'}} + + +# --------------------------------------------------------------------------- +# Tests +# --------------------------------------------------------------------------- + + +class TestBaseCore: + """Direct unit tests for the BaseCore abstract base class.""" + + # ---- construction ---- + + def test_default_construction(self) -> None: + """A minimal concrete subclass should construct without errors.""" + obj = _ConcreteCore(name='Test') + assert obj.name == 'Test' + assert obj.interface is None + assert obj.user_data == {} + + def test_construction_with_interface(self) -> None: + """Passing an interface should trigger generate_bindings.""" + mock_iface = MagicMock() + obj = _ConcreteCore(name='WithIface', interface=mock_iface) + assert obj.interface is mock_iface + mock_iface.generate_bindings.assert_called_once_with(obj) + + def test_construction_with_unique_name(self) -> None: + """unique_name is passed through to ModelBase.""" + obj = _ConcreteCore(name='Uniq', unique_name='my_unique') + assert obj.unique_name == 'my_unique' + + def test_construction_kwargs_stored_as_attributes(self) -> None: + """Transitional kwargs path: extra kwargs become plain instance attrs.""" + child = Parameter('extra_param', 5.0) + obj = _ConcreteCore(name='Kwargs', extra=child, extra2=42) + assert obj.extra is child + assert obj.extra2 == 42 + + # ---- name property ---- + + def test_name_getter(self) -> None: + obj = _ConcreteCore(name='MyName') + assert obj.name == 'MyName' + + def test_name_setter(self) -> None: + obj = _ConcreteCore(name='Original') + obj.name = 'Changed' + assert obj.name == 'Changed' + + # ---- interface property ---- + + def test_interface_set_to_none(self) -> None: + obj = _ConcreteCore(name='NoIface') + obj.interface = None + assert obj.interface is None + + def test_interface_set_triggers_bindings(self) -> None: + obj = _ConcreteCore(name='Late') + mock_iface = MagicMock() + obj.interface = mock_iface + mock_iface.generate_bindings.assert_called_once_with(obj) + + def test_interface_setter_does_not_call_generate_bindings_for_none(self) -> None: + obj = _ConcreteCore(name='NoneIface') + # Setting to None should be safe (no generate_bindings call) + obj.interface = None + assert obj.interface is None + + # ---- generate_bindings ---- + + def test_generate_bindings_raises_when_interface_is_none(self) -> None: + obj = _ConcreteCore(name='NoIface') + with pytest.raises(AttributeError, match='Interface error'): + obj.generate_bindings() + + def test_generate_bindings_propagates_to_children(self) -> None: + """Children with an interface setter receive the parent's interface.""" + mock_iface = MagicMock() + child = _ConcreteCore(name='Child') + child._interface = None # reset so we can observe propagation + obj = _ConcreteCore(name='Parent', child=child) + obj.interface = mock_iface + # The child should have received the interface too. + assert child.interface is mock_iface + + def test_generate_bindings_propagates_to_parameter_children(self) -> None: + """Parameters stored as plain attrs should not break binding propagation.""" + mock_iface = MagicMock() + param = Parameter('p', 1.0) + obj = _ConcreteCore(name='WithParam', p=param) + obj.interface = mock_iface + mock_iface.generate_bindings.assert_called_once_with(obj) + + # ---- _iter_public_children ---- + + def test_iter_public_children_includes_class_attrs(self) -> None: + child = _ConcreteCore(name='Child') + obj = _ConcreteCore(name='Parent', child=child) + children = list(obj._iter_public_children()) + assert child in children + + def test_iter_public_children_includes_instance_attrs(self) -> None: + param = Parameter('p', 1.0) + obj = _ConcreteCore(name='Parent', p=param) + children = list(obj._iter_public_children()) + assert param in children + + def test_iter_public_children_excludes_private(self) -> None: + obj = _ConcreteCore(name='Parent') + obj._private_thing = 'secret' + children = list(obj._iter_public_children()) + names = [getattr(c, 'name', c) for c in children] + assert 'secret' not in names + + def test_iter_public_children_excludes_interface_and_name(self) -> None: + obj = _ConcreteCore(name='Parent') + children = list(obj._iter_public_children()) + assert obj.interface not in children + + def test_iter_public_children_no_duplicates(self) -> None: + """If a child appears both as a class attr and instance attr, only one copy.""" + child = _ConcreteCore(name='Child') + obj = _ConcreteCore(name='Parent', child=child) + # Also set as attr with same id + obj.duplicate_ref = child + children = list(obj._iter_public_children()) + # child should appear only once + assert children.count(child) == 1 + + # ---- _has_interface_setter ---- + + def test_has_interface_setter_true(self) -> None: + assert BaseCore._has_interface_setter(_ConcreteCore) is True + + def test_has_interface_setter_false_for_bare_object(self) -> None: + assert BaseCore._has_interface_setter(object) is False + + def test_has_interface_setter_false_for_parameter(self) -> None: + """Parameter doesn't have an interface property.""" + assert BaseCore._has_interface_setter(Parameter) is False + + # ---- compatibility shims ---- + + def test_get_linkable_attributes(self) -> None: + param = Parameter('p', 1.0) + obj = _ConcreteCore(name='Core', p=param) + result = obj._get_linkable_attributes() + assert param in result + + def test_get_parameters_shim(self) -> None: + param = Parameter('p', 1.0) + obj = _ConcreteCore(name='Core', p=param) + result = obj.get_parameters() + assert param in result + + def test_add_component(self) -> None: + obj = _ConcreteCore(name='Core') + comp = Parameter('comp', 42.0) + obj._add_component('my_comp', comp) + assert obj.my_comp is comp + + # ---- get_all_variables ---- + + def test_get_all_variables_includes_descriptors(self) -> None: + param = Parameter('p', 1.0) + obj = _ConcreteCore(name='Core', p=param) + result = obj.get_all_variables() + assert param in result + + def test_get_all_variables_recurses_into_children(self) -> None: + inner_param = Parameter('inner', 2.0) + child = _ConcreteCore(name='Child', p=inner_param) + obj = _ConcreteCore(name='Parent', child=child) + result = obj.get_all_variables() + assert inner_param in result + + def test_get_all_variables_no_duplicates_across_children(self) -> None: + param = Parameter('shared', 1.0) + child_a = _ConcreteCore(name='A', p=param) + child_b = _ConcreteCore(name='B', p=param) + obj = _ConcreteCore(name='Parent', a=child_a, b=child_b) + result = obj.get_all_variables() + assert result.count(param) == 1 + + # ---- to_dict / as_dict ---- + + def test_to_dict_skips_interface(self) -> None: + mock_iface = MagicMock() + obj = _ConcreteCore(name='Core', interface=mock_iface) + d = obj.to_dict() + assert 'interface' not in d + + def test_to_dict_skips_unique_name_by_default(self) -> None: + obj = _ConcreteCore(name='Core', unique_name='my_unique') + d = obj.to_dict() + assert 'unique_name' not in d + + def test_to_dict_includes_name(self) -> None: + obj = _ConcreteCore(name='MyName') + d = obj.to_dict() + assert d.get('name') == 'MyName' + + def test_as_dict_is_alias_for_to_dict(self) -> None: + obj = _ConcreteCore(name='Core') + assert obj.as_dict() == obj.to_dict() + + def test_to_dict_respects_custom_skip(self) -> None: + obj = _ConcreteCore(name='Core') + d = obj.to_dict(skip=['name']) + assert 'name' not in d + + def test_to_dict_skip_not_mutated_by_callee(self) -> None: + """Caller's skip list must not be mutated.""" + obj = _ConcreteCore(name='Core') + skip = ['name'] + obj.to_dict(skip=skip) + assert skip == ['name'] # not appended-to + + # ---- repr ---- + + def test_repr_returns_yaml_string(self) -> None: + obj = _ConcreteCore(name='Test') + r = repr(obj) + assert 'Test' in r + assert 'concrete' in r + + # ---- user_data ---- + + def test_user_data_is_dict(self) -> None: + obj = _ConcreteCore(name='Core') + obj.user_data['key'] = 'value' + assert obj.user_data['key'] == 'value' + + # ---- round-trip ---- + + def test_basic_round_trip_via_material(self) -> None: + """Round-trip through a real subclass (Material) to verify BaseCore serialization.""" + from easyreflectometry.sample.elements.materials.material import Material + + global_object.map._clear() + obj = Material(sld=2.0, isld=0.5, name='TestMat') + d = obj.to_dict() + global_object.map._clear() + + restored = Material.from_dict(d) + assert restored.name == 'TestMat' + assert restored.sld.value == 2.0 + assert restored.isld.value == 0.5 + + def test_round_trip_skips_interface(self) -> None: + """Round-trip via to_dict → from_dict should strip the interface.""" + global_object.map._clear() + obj = _ConcreteCore(name='WithIface') + d = obj.to_dict() + assert 'interface' not in d diff --git a/tests/test_project.py b/tests/test_project.py index 73aeca85..ec85b3f2 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -377,11 +377,13 @@ def test_as_dict(self): keys.sort() assert keys == [ 'calculator', + 'file_format', 'fitter_minimizer', 'info', 'models', 'with_experiments', ] + assert project_dict['file_format'] == Project.FILE_FORMAT assert project_dict['info'] == { 'name': 'DefaultEasyReflectometryProject', 'short_description': 'Reflectometry, 1D', @@ -417,6 +419,44 @@ def remove_interface(d): remove_interface(project_dict['models']) assert project_dict['models'] == models_dict + def test_from_dict_missing_file_format_raises(self): + """Loading a dict without file_format should raise ValueError.""" + project = Project() + bad_dict = {'info': {}, 'with_experiments': False, 'models': {'data': []}} + with pytest.raises(ValueError, match='predates file_format=2'): + project.from_dict(bad_dict) + + def test_from_dict_wrong_file_format_raises(self): + """Loading a dict with an unsupported file_format should raise ValueError.""" + project = Project() + bad_dict = { + 'file_format': 99, + 'info': {}, + 'with_experiments': False, + 'models': {'data': []}, + } + with pytest.raises(ValueError, match='Unsupported project file_format'): + project.from_dict(bad_dict) + + def test_from_dict_correct_file_format_succeeds(self): + """Loading a dict with the correct file_format should work.""" + global_object.map._clear() + # Build a valid project dict with at least one model + src_project = Project() + src_project._info['name'] = 'Test' + src_project._info['short_description'] = 'Desc' + src_project._info['modified'] = '01.01.2025 00:00' + src_project.default_model() # ensures at least one model exists + src_project._with_experiments = False + good_dict = src_project.as_dict() + global_object.map._clear() + + project = Project() + project.from_dict(good_dict) + assert project._info['name'] == 'Test' + assert project._with_experiments is False + assert len(project._models) >= 1 + def test_as_dict_materials_not_in_model(self): # When project = Project() From 7324189f3be62c278e8af7014f5f858d01586447 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 5 Jun 2026 16:05:25 +0200 Subject: [PATCH 14/22] Bayesian analysis (#352) * initial commit with examples * ruff format * refactor core modifications to live in reflectometry lib only * modified the notebook a bit * refactored MCMC sampling to easyscience module * added pass-through for cancellation and total number of calculations * silly typo * yet another linting * moved the notebook to the correct location and fixed the formatting * added more initial arguments to sample. Added unit tests * prettify charts. Updated notebook * fixed issue with the notebook * move file fetch to reflectometry/data * PR review fixes * be careful with small chains * ruff * try to use explicit dtype for Ubuntu * another attempt at fixing failing test * better corner and distribution plots * updates to the Bayesian API after changes to core * use bayesian_extend * minor fixes * fix failing test * test against develop, so we can merge the PR * use mcmc_sample * fixed tests * minor notebook fix --- BAYESIAN_IN_ERL.md | 361 + .../advancedfitting/bayesian_bumps.ipynb | 734 + .../tutorials/advancedfitting/example.ort | 448 + .../advancedfitting/multi_contrast.ipynb | 11 +- .../tutorials/fitting/material_solvated.ipynb | 11 +- docs/docs/tutorials/fitting/monolayer.ipynb | 12 +- docs/docs/tutorials/fitting/repeating.ipynb | 11 +- .../tutorials/fitting/simple_fitting.ipynb | 11 +- .../simulation/resolution_functions.ipynb | 24 +- pixi.lock | 21525 ++++++++-------- pyproject.toml | 5 +- src/easyreflectometry/__init__.py | 2 + src/easyreflectometry/analysis/__init__.py | 23 + src/easyreflectometry/analysis/bayesian.py | 1376 + src/easyreflectometry/fitting.py | 83 + tests/_static/amor_reduced_iofq.ort | 236 + tests/test_bayesian.py | 476 + tests/test_fitting.py | 263 + tests/test_ort_file.py | 29 +- 19 files changed, 14916 insertions(+), 10725 deletions(-) create mode 100644 BAYESIAN_IN_ERL.md create mode 100644 docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb create mode 100644 docs/docs/tutorials/advancedfitting/example.ort create mode 100644 src/easyreflectometry/analysis/__init__.py create mode 100644 src/easyreflectometry/analysis/bayesian.py create mode 100644 tests/_static/amor_reduced_iofq.ort create mode 100644 tests/test_bayesian.py diff --git a/BAYESIAN_IN_ERL.md b/BAYESIAN_IN_ERL.md new file mode 100644 index 00000000..dc99953f --- /dev/null +++ b/BAYESIAN_IN_ERL.md @@ -0,0 +1,361 @@ +# Bayesian Analysis in EasyReflectometryLib — Implementation Plan + +## Current State + +- `BAYESIAN_BUMPS.md` (in `MD/`) describes a 3-phase plan. Phase 1 + (docs/notebook) is complete. +- `bayesian_bumps.py` (attached notebook) works but users must directly + import from `bumps.fitters`, `bumps.names`, `bumps.parameter` — a + leaky abstraction. +- The `Bumps` minimizer in `easyscience` + (`core/src/easyscience/fitting/minimizers/minimizer_bumps.py`) only + exposes **classical optimization** methods (`amoeba`, `newton`, `lm`), + NOT the DREAM/MCMC sampler. +- The `AvailableMinimizers` enum only has `Bumps`, `Bumps_simplex`, + `Bumps_newton`, `Bumps_lm`. This should remain optimizer-focused; + DREAM should be exposed as a sampling workflow, not as another + minimizer choice. +- `MultiFitter` in reflectometry-lib currently only has `fit()` and + `fit_single_data_set_1d()`. + +## Goal + +Users should be able to run Bayesian MCMC sampling with a **clean +high-level API** like: + +```python +fitter = MultiFitter(model) +fitter.switch_minimizer(AvailableMinimizers.Bumps) + +# Classical fit first +analysed = fitter.fit(data) + +# Bayesian sampling +posterior = fitter.sample(data, samples=5000, burn=1000, thin=10) + +# Analyze +from easyreflectometry.analysis.bayesian import plot_corner, posterior_summary +plot_corner(posterior) +print(posterior_summary(posterior)) +``` + +Important API boundary: `fit()` remains classical optimization only. +Bayesian DREAM sampling is exposed through `sample()` so users do not +receive sampler-shaped results from an optimizer-shaped API. + +## Implementation Plan + +### Step 1 — Keep DREAM separate from `AvailableMinimizers` + +**File**: `core/src/easyscience/fitting/available_minimizers.py` + +Do **not** add `Bumps_dream` as a normal `AvailableMinimizers` member. +The enum is currently used to instantiate minimizer backends and to +route calls through `Fitter.fit()`, which expects optimizer-style +`FitResults`. DREAM is an MCMC sampler and returns a sampler state/chain +rather than a best-fit result. + +Use `AvailableMinimizers.Bumps` to select the BUMPS backend, then expose +DREAM through a dedicated `sample()` method. This avoids making +`project.minimizer = AvailableMinimizers.Bumps_dream` look like a valid +classical fitting mode. + +### Step 2 — Add dedicated DREAM sampling support to the Bumps minimizer (core repo) + +**File**: `core/src/easyscience/fitting/minimizers/minimizer_bumps.py` + +**2a.** Keep `supported_methods()` optimizer-only (`amoeba`, `newton`, +`lm`). Do not add `'dream'` there unless the EasyScience fitting +abstraction is later split into optimizer and sampler concepts. + +**2b.** Add a new method `sample()` to the `Bumps` class: + +```python +def sample( + self, + x: np.ndarray, + y: np.ndarray, + weights: np.ndarray, + samples: int = 10000, + burn: int = 2000, + thin: int = 10, + chains: int | None = None, + population: int | None = None, + model: Callable | None = None, + parameters: list | None = None, + progress_callback: Callable | None = None, + seed: int | None = None, + **kwargs, +) -> dict: + """Run Bayesian MCMC sampling using BUMPS DREAM sampler. + + Returns a dict with: + - 'draws': np.ndarray, shape (n_samples, n_params) — posterior samples + - 'param_names': list[str] — parameter names + - 'state': DreamState — raw BUMPS state for save/restore + - 'logp': np.ndarray — log-posterior values + """ +``` + +The implementation would: + +1. Build the `Curve` model + `FitProblem` (reuse `_make_model()` logic) +2. Translate user-friendly aliases to BUMPS DREAM settings and call + `bumps_fit(problem, method='dream', samples=samples, burn=burn, thin=thin, pop=population, ...)` +3. Extract `result.state.draw().points` and return structured dict +4. Preserve and restore the EasyScience global object stack state, + mirroring the existing `fit()` implementation +5. Handle multi-dataset via the same `MultiFitter._precompute_reshaping` + pattern + +**2c.** Do **not** modify `fit()` to handle `method='dream'`, and do +**not** delegate `fit(method='dream')` to `sample()`. `fit()` returns +`FitResults`; `sample()` returns posterior samples and sampler metadata. +Keeping the methods separate prevents incompatible return types from +leaking into `Fitter.fit()` and reflectometry-lib `MultiFitter.fit()`. + +Recommended alias mapping: + +| Public argument | BUMPS DREAM setting | Rationale | +| ---------------- | --------------------------- | ----------------------------------------------------------------------- | +| `samples` | `samples` | Clear user-facing chain length; prefer over optimizer-oriented `steps`. | +| `burn` | `burn` | Matches BUMPS and common MCMC terminology. | +| `thin` | `thin` | Matches BUMPS and common MCMC terminology. | +| `chains` | `pop` | User-friendly MCMC wording; maps to BUMPS population count. | +| `population` | `pop` | BUMPS-aware alias for advanced users. | +| `initialization` | `init` | More readable than `init`, but pass through to BUMPS. | +| `seed` | RNG seeding before sampling | Expose reproducibility without requiring users to know BUMPS internals. | + +If both `chains` and `population` are provided, raise `ValueError` +unless they match. Accept `steps` only as a deprecated alias for +`samples`, with a warning, because `steps` already means optimizer +budget in EasyScience `Bumps.fit()`. + +### Step 3 — Add `sample()` to reflectometry-lib `MultiFitter` + +**File**: `reflectometry-lib/src/easyreflectometry/fitting.py` + +Add a `sample()` method to `MultiFitter`: + +```python +def sample( + self, + data: sc.DataGroup, + samples: int = 10000, + burn: int = 2000, + thin: int = 10, + chains: int | None = None, + population: int | None = None, + seed: int | None = None, + objective: str | None = None, +) -> dict: + """Run Bayesian MCMC sampling on reflectometry data. + + :param data: DataGroup with reflectivity data. + :param samples: Number of retained DREAM samples requested from BUMPS. + :param burn: Burn-in steps. + :param thin: Thinning interval. + :param chains: User-friendly alias for BUMPS DREAM population count. + :param population: BUMPS DREAM population count (`pop`) for advanced users. + :param seed: Random seed for reproducibility. + :param objective: Zero-variance handling strategy. + :return: Dict with posterior samples, parameter names, and sampler state. + """ +``` + +Internally: + +1. Reuse `_prepare_fit_arrays` for data preparation +2. Mirror the EasyScience `Fitter.fit()` lifecycle for reshaping, fit + function wrapping, and restoration +3. Delegate to `self.easy_science_multi_fitter.minimizer.sample(...)` + for the MCMC +4. Handle multi-model / multi-contrast aggregation as one joint + posterior +5. Return structured posterior dict or `PosteriorResults` + +The `MultiFitter` currently stores `self.easy_science_multi_fitter` +which has `.minimizer` — we'll call `sample()` on it when the minimizer +is a `Bumps` instance. + +### Step 4 — Create Bayesian analysis module in reflectometry-lib + +**New file**: +`reflectometry-lib/src/easyreflectometry/analysis/__init__.py` **New +file**: `reflectometry-lib/src/easyreflectometry/analysis/bayesian.py` + +The `bayesian.py` module provides: + +```python +class PosteriorResults: + """Container for Bayesian posterior samples with analysis methods.""" + + draws: np.ndarray # (n_samples, n_params) + param_names: list[str] + logp: np.ndarray | None + sampler_state: Any | None + + def summary(self) -> str: + """Return formatted summary table with mean, sd, HDI for each parameter.""" + + def corner(self, **kwargs) -> None: + """Plot parameter correlation corner plot using the `corner` library.""" + + def credible_interval(self, alpha: float = 0.95) -> dict: + """Return {param_name: (lower, upper)} credible intervals.""" + + def gelman_rubin(self) -> dict: + """Compute R-hat convergence diagnostic.""" + +def posterior_summary(draws, param_names) -> str: ... +def plot_corner(draws, param_names, **kwargs) -> None: ... +def plot_trace(draws, param_names, **kwargs) -> None: ... +def credible_intervals(draws, param_names, alpha=0.95) -> dict: ... +``` + +**Posterior predictive functions** (reflectivity & SLD): + +```python +def posterior_predictive_reflectivity( + draws, param_names, model, q_values, n_samples=200 +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """Return (median, lower_95, upper_95) reflectivity arrays.""" + +def posterior_sld_profile( + draws, param_names, model, n_samples=200 +) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + """Return (z, median, lower_95, upper_95) SLD profile arrays.""" +``` + +Posterior predictive helpers must save original parameter values and +errors before applying any posterior draw, and restore them in a +`finally` block after prediction. Parameter lookup should use +EasyScience parameter `unique_name` values, matching the BUMPS names +after removing the minimizer prefix, rather than display names. This +avoids leaving the model mutated after plotting and avoids collisions +when repeated models or multi-contrast fits contain similarly named +parameters. + +### Step 5 — Dependencies + +Add to `pyproject.toml` in reflectometry-lib: + +```toml +[project.optional-dependencies] +bayesian = ["corner>=2.2", "arviz>=0.18"] +``` + +Make `corner` and `arviz` optional imports — the analysis module should +work with graceful fallbacks when they're not installed. + +### Step 6 — Update exports + +**File**: `reflectometry-lib/src/easyreflectometry/__init__.py` + +Add `PosteriorResults` and analysis functions to the public API if +desired. + +### Step 7 — Update the example notebook + +**File**: +`reflectometry-lib/docs/src/tutorials/advancedfitting/bayesian_bumps.py` + +Replace low-level BUMPS calls with the new high-level API: + +- `fitter.sample(data, samples=500, burn=100, thin=10)` instead of + manual `FitProblem` + `bumps_fit` +- `plot_corner(posterior['draws'], posterior['param_names'])` instead of + manual `corner.corner()` +- `posterior_summary(...)` instead of manual numpy statistics + +### Step 8 — Tests + +**File**: `reflectometry-lib/tests/test_bayesian.py` (new) + +```python +def test_sample_basic(): ... +def test_posterior_summary_format(): ... +def test_corner_plot_does_not_crash(): ... +def test_credible_intervals(): ... +def test_sample_seed_reproducibility(): ... +``` + +Also add a test in `core/tests/` for the `Bumps.sample()` method. + +## Architecture Diagram + +``` +User Code + │ + ├─ fitter.fit(data) ──► classical chi² minimization + ├─ fitter.sample(data, ...) ──► Bayesian DREAM MCMC + │ + ▼ +reflectometry-lib MultiFitter + │ ._prepare_fit_arrays() ← reused from fit() + │ delegates to ↓ + ▼ +easyscience Bumps minimizer + │ .fit(x, y, weights) ──► amoeba/newton/lm + │ .sample(x, y, weights, ...) ──► DREAM MCMC (NEW) + │ + ▼ +bumps.fitters.fit / FitProblem / Curve + └──► reflectivity model evaluation via fit_func + +Post-hoc analysis: + reflectometry-lib analysis.bayesian + ├── PosteriorResults (container) + ├── plot_corner() → corner.corner() + ├── posterior_summary() → numpy stats + └── posterior_predictive_reflectivity() → model.interface.fit_func() +``` + +## Risk Assessment + +| Risk | Mitigation | +| -------------------------------------------- | -------------------------------------------------------------------------------- | +| DREAM may not converge with default settings | Expose `samples`, `burn`, `thin`, `chains`/`population`; document best practices | +| MCMC is 10-100× slower than least-squares | Document that classical fit first is recommended; add progress callback | +| `corner` / `arviz` may not be installed | Make optional dependencies with graceful fallbacks | +| Multi-dataset sampling aggregation | Follow existing `MultiFitter._precompute_reshaping` pattern | +| BUMPS DREAM API changes | Pin bumps version; wrap in our API | +| Reproducibility | Expose `seed` parameter; document how to save/load DreamState | +| Model mutation during posterior prediction | Save/restore original parameter values and map draws by `unique_name` | + +## Files to Create / Modify + +### Create: + +1. `reflectometry-lib/src/easyreflectometry/analysis/__init__.py` +2. `reflectometry-lib/src/easyreflectometry/analysis/bayesian.py` +3. `reflectometry-lib/tests/test_bayesian.py` + +### Modify: + +4. `core/src/easyscience/fitting/available_minimizers.py` — no + `Bumps_dream`; optionally document that samplers are exposed + separately +5. `core/src/easyscience/fitting/minimizers/minimizer_bumps.py` — add + dedicated `sample()` method without adding `'dream'` to optimizer + methods +6. `reflectometry-lib/src/easyreflectometry/fitting.py` — add `sample()` + to `MultiFitter` +7. `reflectometry-lib/src/easyreflectometry/__init__.py` — optional: + export new classes +8. `reflectometry-lib/pyproject.toml` — add optional `bayesian` + dependencies +9. `reflectometry-lib/docs/src/tutorials/advancedfitting/bayesian_bumps.py` + — update to use new API + +## Implementation Order + +1. **core changes** (Steps 1-2): Add `Bumps.sample()` method while + keeping DREAM out of optimizer enum/method dispatch +2. **reflectometry-lib fitting** (Step 3): Add `MultiFitter.sample()` +3. **reflectometry-lib analysis** (Step 4): Create + `analysis/bayesian.py` with corner plot & stats +4. **Dependencies** (Step 5): Add optional deps to pyproject.toml +5. **Exports** (Step 6): Update `__init__.py` +6. **Example update** (Step 7): Update notebook to use new API +7. **Tests** (Step 8): Add test coverage diff --git a/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb b/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb new file mode 100644 index 00000000..1c7e1bf6 --- /dev/null +++ b/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb @@ -0,0 +1,734 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "649cf9aa", + "metadata": {}, + "source": [ + "# Bayesian Fitting with BUMPS\n", + "\n", + "This notebook demonstrates the full high-level Bayesian MCMC API in\n", + "EasyReflectometry.\n", + "\n", + "It covers:\n", + "\n", + "- Building a reflectometry model with realistic bounds (critical for MCMC).\n", + "- Classical optimisation first (good starting point for Bayesian sampling).\n", + "- High-level DREAM MCMC sampling via\n", + " ``MultiFitter.mcmc_sample()`` and ``PosteriorResults``.\n", + "- Posterior inspection: summary table, marginal distributions, corner plot,\n", + " trace plot, credible intervals, Gelman-Rubin R-hat.\n", + "- Posterior-predictive checks: reflectivity and SLD profile with 95 %\n", + " credible bands.\n", + "\n", + "All posterior plots are rendered as **interactive Plotly figures**, the\n", + "same ones shown by the EasyReflectometryApp Bayesian Posterior tab.\n", + "\n", + "**Note**: Requires ``arviz`` and ``plotly`` (install via\n", + "``pip install easyreflectometry[dev]``)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "61aa83ac", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:06.282846Z", + "iopub.status.busy": "2026-05-29T06:29:06.282846Z", + "iopub.status.idle": "2026-05-29T06:29:09.516170Z", + "shell.execute_reply": "2026-05-29T06:29:09.516170Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All libraries imported successfully.\n" + ] + } + ], + "source": [ + "import warnings\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pooch\n", + "from easyscience.fitting import AvailableMinimizers\n", + "\n", + "from easyreflectometry.analysis.bayesian import PosteriorResults\n", + "from easyreflectometry.analysis.bayesian import plot_corner\n", + "from easyreflectometry.analysis.bayesian import plot_trace\n", + "from easyreflectometry.analysis.bayesian import posterior_predictive_reflectivity\n", + "from easyreflectometry.analysis.bayesian import posterior_predictive_sld_profile\n", + "from easyreflectometry.calculators import CalculatorFactory\n", + "from easyreflectometry.data.measurement import load\n", + "from easyreflectometry.fitting import MultiFitter\n", + "from easyreflectometry.model import Model\n", + "from easyreflectometry.model import PercentageFwhm\n", + "from easyreflectometry.sample import Layer\n", + "from easyreflectometry.sample import Material\n", + "from easyreflectometry.sample import Multilayer\n", + "from easyreflectometry.sample import Sample\n", + "\n", + "warnings.filterwarnings('ignore')\n", + "\n", + "print('All libraries imported successfully.')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "14986b98", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:09.517778Z", + "iopub.status.busy": "2026-05-29T06:29:09.517778Z", + "iopub.status.idle": "2026-05-29T06:29:09.958508Z", + "shell.execute_reply": "2026-05-29T06:29:09.958508Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data loaded with keys: ['data', 'coords', 'attrs']\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# ---- Load experimental data -------------------------------------------------\n", + "# Fetch the .ort test data from the easyscience/reflectometry data repository.\n", + "data_path = pooch.retrieve(\n", + " url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/example.ort',\n", + " known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n", + ")\n", + "data = load(data_path)\n", + "print('Data loaded with keys:', list(data.keys()))\n", + "\n", + "# Quick look at the data\n", + "qz = data['coords']['Qz_0'].values\n", + "r_data = data['data']['R_0'].values\n", + "\n", + "plt.figure(figsize=(7, 4))\n", + "plt.semilogy(qz, r_data, 'o', label='Data')\n", + "plt.xlabel('Q / Å⁻¹')\n", + "plt.ylabel('Reflectivity')\n", + "plt.title('Experimental data (example.ort)')\n", + "plt.legend()\n", + "plt.grid(True, alpha=0.3)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "cd56a6eb", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:09.960548Z", + "iopub.status.busy": "2026-05-29T06:29:09.960548Z", + "iopub.status.idle": "2026-05-29T06:29:09.973595Z", + "shell.execute_reply": "2026-05-29T06:29:09.973595Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model created with the following free parameters:\n", + " background: value=1e-06, bounds=(1e-07, 1e-05)\n", + " sld: value=2.0, bounds=(0.5, 4.0)\n", + " thickness: value=250.0, bounds=(100, 400)\n", + " scale: value=1.0, bounds=(0.8, 1.2)\n" + ] + } + ], + "source": [ + "# ---- Create a monolayer model (Si / Film / D₂O) ----------------------------\n", + "si = Material(sld=2.07, isld=0.0, name='Si')\n", + "film = Material(sld=2.0, isld=0.0, name='Film')\n", + "d2o = Material(sld=6.36, isld=0.0, name='D2O')\n", + "\n", + "si_layer = Layer(material=si, thickness=0.0, roughness=3.0, name='Si')\n", + "film_layer = Layer(material=film, thickness=250.0, roughness=3.0, name='Film')\n", + "d2o_layer = Layer(material=d2o, thickness=0.0, roughness=3.0, name='D2O')\n", + "\n", + "sample = Sample(\n", + " Multilayer(si_layer),\n", + " Multilayer(film_layer),\n", + " Multilayer(d2o_layer),\n", + " name='Monolayer Sample',\n", + ")\n", + "\n", + "resolution = PercentageFwhm(0.02)\n", + "model = Model(\n", + " sample=sample,\n", + " scale=1.0,\n", + " background=1e-6,\n", + " resolution_function=resolution,\n", + " name='Monolayer Model',\n", + ")\n", + "\n", + "# ---- Make key parameters free with realistic bounds (essential for MCMC) -----\n", + "film_layer.thickness.fixed = False\n", + "film_layer.thickness.bounds = (100, 400)\n", + "\n", + "film.sld.fixed = False\n", + "film.sld.bounds = (0.5, 4.0)\n", + "\n", + "model.scale.fixed = False\n", + "model.scale.bounds = (0.8, 1.2)\n", + "\n", + "model.background.fixed = False\n", + "model.background.bounds = (1e-7, 1e-5)\n", + "\n", + "print('Model created with the following free parameters:')\n", + "for p in model.get_parameters():\n", + " if not p.fixed:\n", + " print(f' {p.name}: value={p.value}, bounds={p.bounds}')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "991e1169", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:09.974614Z", + "iopub.status.busy": "2026-05-29T06:29:09.974614Z", + "iopub.status.idle": "2026-05-29T06:29:09.982333Z", + "shell.execute_reply": "2026-05-29T06:29:09.982333Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitter ready with minimizer: Bumps\n" + ] + } + ], + "source": [ + "# ---- Set up the calculator and fitter ---------------------------------------\n", + "interface = CalculatorFactory()\n", + "interface.switch('refnx') # or 'refl1d'\n", + "model.interface = interface\n", + "\n", + "fitter = MultiFitter(model)\n", + "# Use the BUMPS backend — DREAM sampling is only available through BUMPS.\n", + "fitter.switch_minimizer(AvailableMinimizers.Bumps)\n", + "\n", + "print('Fitter ready with minimizer:', fitter.easy_science_multi_fitter.minimizer.name)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "eb0f989e", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:09.983788Z", + "iopub.status.busy": "2026-05-29T06:29:09.983788Z", + "iopub.status.idle": "2026-05-29T06:29:11.760084Z", + "shell.execute_reply": "2026-05-29T06:29:11.760084Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Classical fit successful: True\n", + "Reduced χ² ≈ 73.7860402885366\n" + ] + }, + { + "data": { + "image/png": "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b5OaY0/QrZ636WfIc0cYBr5EREQ6EoyaY+/niDMZO962jcLLaATiEt0b3IuSBIVkxWWTA+oiHJcaIiIioi7zlD+MyE9VSxzLam9yKpneSF/mlvSHGV8iIiKKirZtRO1h4EtERERR0baNqD0sdSAiIiIiXWDgS0RERES6wFIHIiIi0i2XS2tVm0zRK+oD3/3792POnDk+l1955RXMnj07rOMiIiKi8Np6rKJ5MQ67w73YhiztPPeyi1CQEO7RUShEfeA7dOhQ7NixQ52vqalB//79MWPGjHAPi4iIiMIc9Er/4UpbI7It0n84XvUf3nO6Ck+s24d5k3IwPTs73MOkINNVje9bb72FadOmISkpKdxDISIiojCWN0imV4Le/n0SkRRvQozRoE4LMxJRXdeIV/9Zpu5H0SXsge8nn3yCG264Afn5+TAYDHjjjTda3eeZZ55RmVqz2YyJEydi8+bNXfpZa9as8Sl7ICIiIv2QQHZfaTVe23YSu09XIcsSr2IPb3I50xKHoxX1OFBWE7axUpSWOtTW1mLMmDG49957cfPNN7e6ffXq1ViwYAGef/55FfQuW7YMM2fOVLW62U1fQYwdOxYOh6PVYz/44AMVUIvq6mps3LgRq1at6oG9IiIiokit562y2XG2xo6a+kYUZCQhLSHW576y7LLdoanML0WXsAe+s2bNUlsgTz/9NO6//37cc8896rIEwGvXrsWf//xnPPLII+o6Tw1vW958801cc801KmvcloaGBrV5SMAsXC6X2rpKHqtpWreeg3oHzrV+cK71hfPde209dl7V7VbVNSLLEoeEODPO2+yornPg4BkrhmQnq44OHnV2J2JjDLDEx3C+e4mOzlPYA9+22O12bN26FT/72c+arzMajZg+fTo2bdrU6TKHBx54oN37LV68GI8++mir68+ePYv6+np0Z0KqqqrUH03ZB4penGv94FzrC+e7d3JpGl74+AgqaurQNzUeBrgQY9CQGBeD2gan6uZw7FwthsZIGweDmt8zVQ0YkGZCqsGGsrILyTCKXFartfcHvuXl5XA6ncjJyfG5Xi7v27evw88jf6ikLvi1115r974SZEtphXfGt6CgAFlZWUhJSenWH0ypG5Ln4R/M6Ma51g/Otb5wvnunfaVWnLI6kJuWCHP8hbCnsI8RB6WNmdMFm92JBqcRMTEGlNfYkZFs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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# ---- Classical fit first ----------------------------------------------------\n", + "# A classical optimisation gives a good starting point and a sanity check\n", + "# before launching the (much more expensive) MCMC sampler.\n", + "\n", + "analysed = fitter.fit(data)\n", + "\n", + "print('Classical fit successful:', analysed.get('success', 'N/A'))\n", + "print('Reduced χ² ≈', analysed.get('reduced_chi', 'N/A'))\n", + "\n", + "# Plot the fit\n", + "r_model = analysed['R_0_model'].values\n", + "\n", + "plt.figure(figsize=(8, 5))\n", + "plt.semilogy(qz, r_data, 'o', label='Data', alpha=0.7)\n", + "plt.semilogy(qz, r_model, '-', label='Classical BUMPS fit', linewidth=2)\n", + "plt.xlabel('Q / Å⁻¹')\n", + "plt.ylabel('Reflectivity')\n", + "plt.title('Classical fit before Bayesian sampling')\n", + "plt.legend()\n", + "plt.grid(True, alpha=0.3)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20c9b0e0", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:29:11.762093Z", + "iopub.status.busy": "2026-05-29T06:29:11.762093Z", + "iopub.status.idle": "2026-05-29T06:30:41.903328Z", + "shell.execute_reply": "2026-05-29T06:30:41.903328Z" + } + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "Fitter.mcmc_sample() got an unexpected keyword argument 'chains'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# ---- Bayesian MCMC sampling -------------------------------------------------\u001b[39;00m\n\u001b[32m 2\u001b[39m \u001b[38;5;66;03m# ``MultiFitter.mcmc_sample()`` delegates to the BUMPS DREAM sampler.\u001b[39;00m\n\u001b[32m 3\u001b[39m \u001b[38;5;66;03m# All keyword arguments are forwarded with user-friendly names:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 7\u001b[39m \u001b[38;5;66;03m# ``chains`` ← DREAM population count (alias for ``pop``)\u001b[39;00m\n\u001b[32m 8\u001b[39m \u001b[38;5;66;03m# ``population``← BUMPS‑native ``pop`` for advanced users\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m posterior_dict = \u001b[43mfitter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmcmc_sample\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43msamples\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m2000\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Short for demo; use 20 k+ in production\u001b[39;49;00m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mburn\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m500\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mthin\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m10\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m)\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33mDREAM sampling complete.\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 18\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m'\u001b[39m\u001b[33m Posterior shape : \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mposterior_dict[\u001b[33m\"\u001b[39m\u001b[33mdraws\u001b[39m\u001b[33m\"\u001b[39m].shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\projects\\easy\\ERA\\reflectometry-lib\\src\\easyreflectometry\\fitting.py:451\u001b[39m, in \u001b[36mMultiFitter.mcmc_sample\u001b[39m\u001b[34m(self, data, samples, burn, thin, chains, population, objective, initializer, resume_state, progress_callback, abort_test)\u001b[39m\n\u001b[32m 449\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m initializer \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 450\u001b[39m sampler_kwargs[\u001b[33m'\u001b[39m\u001b[33minit\u001b[39m\u001b[33m'\u001b[39m] = initializer\n\u001b[32m--> \u001b[39m\u001b[32m451\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43measy_science_multi_fitter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmcmc_sample\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 452\u001b[39m \u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m=\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 453\u001b[39m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m=\u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 454\u001b[39m \u001b[43m \u001b[49m\u001b[43mweights\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdy\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 455\u001b[39m \u001b[43m \u001b[49m\u001b[43msamples\u001b[49m\u001b[43m=\u001b[49m\u001b[43msamples\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 456\u001b[39m \u001b[43m \u001b[49m\u001b[43mburn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mburn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 457\u001b[39m \u001b[43m \u001b[49m\u001b[43mthin\u001b[49m\u001b[43m=\u001b[49m\u001b[43mthin\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 458\u001b[39m \u001b[43m \u001b[49m\u001b[43mchains\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchains\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 459\u001b[39m \u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 460\u001b[39m \u001b[43m \u001b[49m\u001b[43mresume_state\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresume_state\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 461\u001b[39m \u001b[43m \u001b[49m\u001b[43msampler_kwargs\u001b[49m\u001b[43m=\u001b[49m\u001b[43msampler_kwargs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 462\u001b[39m \u001b[43m \u001b[49m\u001b[43mprogress_callback\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprogress_callback\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 463\u001b[39m \u001b[43m \u001b[49m\u001b[43mabort_test\u001b[49m\u001b[43m=\u001b[49m\u001b[43mabort_test\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 464\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[31mTypeError\u001b[39m: Fitter.mcmc_sample() got an unexpected keyword argument 'chains'" + ] + } + ], + "source": [ + "# ---- Bayesian MCMC sampling -------------------------------------------------\n", + "# ``MultiFitter.mcmc_sample()`` delegates to the BUMPS DREAM sampler.\n", + "# All keyword arguments are forwarded with user-friendly names:\n", + "# ``samples`` ← total retained samples\n", + "# ``burn`` ← burn‑in steps\n", + "# ``thin`` ← thinning interval\n", + "# ``population``← BUMPS‑native ``pop`` for advanced users\n", + "\n", + "posterior_dict = fitter.mcmc_sample(\n", + " data,\n", + " samples=2000, # Short for demo; use 20 k+ in production\n", + " burn=500,\n", + " thin=10,\n", + ")\n", + "\n", + "print('DREAM sampling complete.')\n", + "print(f' Posterior shape : {posterior_dict[\"draws\"].shape}')\n", + "print(f' Parameters : {posterior_dict[\"param_names\"]}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f23934a0", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:41.905335Z", + "iopub.status.busy": "2026-05-29T06:30:41.905335Z", + "iopub.status.idle": "2026-05-29T06:30:41.908528Z", + "shell.execute_reply": "2026-05-29T06:30:41.908528Z" + } + }, + "outputs": [], + "source": [ + "# ---- Wrap in PosteriorResults -----------------------------------------------\n", + "# ``PosteriorResults`` gives you a convenient object with built-in analysis\n", + "# methods. You can also use the raw ``dict`` with the standalone functions\n", + "# — both styles are shown below.\n", + "\n", + "posterior = PosteriorResults(\n", + " draws=posterior_dict['draws'],\n", + " param_names=posterior_dict['param_names'],\n", + " logp=posterior_dict.get('logp'),\n", + " sampler_state=posterior_dict.get('state'),\n", + ")\n", + "\n", + "print(posterior)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef300cb1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:41.909855Z", + "iopub.status.busy": "2026-05-29T06:30:41.909855Z", + "iopub.status.idle": "2026-05-29T06:30:41.913882Z", + "shell.execute_reply": "2026-05-29T06:30:41.913882Z" + } + }, + "outputs": [], + "source": [ + "# ---- Posterior summary table ------------------------------------------------\n", + "# ``.summary()`` prints mean, standard deviation and 95 % HDI for each parameter.\n", + "\n", + "print(posterior.summary())" + ] + }, + { + "cell_type": "markdown", + "id": "d1f0a300", + "metadata": {}, + "source": [ + "## Interactive posterior plots\n", + "\n", + "The next three cells render the same Plotly figures that are shown on the\n", + "Bayesian Posterior tab of the EasyReflectometryApp:\n", + "\n", + "* **Marginals** — per-parameter distribution: histogram + smooth KDE marginal,\n", + " shaded 95% credible interval, and median / best-sample lines\n", + " (`plot_distribution` or `posterior.distribution()`)\n", + "* **Corner plot** — pairwise marginals + 2-D contours + scatter (`plot_corner`)\n", + "* **Traces** — per-chain trace + marginal histogram (`plot_trace`)\n", + "\n", + "The standalone helpers are called with ``return_figure=True`` so they return a\n", + "Plotly ``Figure`` that we render in the notebook with ``fig.show()``; the\n", + "``PosteriorResults`` methods return the figure directly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b9d3c2a", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:41.914887Z", + "iopub.status.busy": "2026-05-29T06:30:41.914887Z", + "iopub.status.idle": "2026-05-29T06:30:43.463799Z", + "shell.execute_reply": "2026-05-29T06:30:43.463252Z" + } + }, + "outputs": [], + "source": [ + "# ---- Marginal posterior distributions ---------------------------------------\n", + "# One panel per free parameter, each overlaying the posterior histogram, a\n", + "# smooth Gaussian-KDE marginal, the shaded 95% credible interval, and the\n", + "# median / best-sample reference lines. Mirrors the \"Marginals\" sub-tab in\n", + "# the EasyReflectometryApp.\n", + "\n", + "# The PosteriorResults method passes ``logp`` through automatically so the\n", + "# best posterior sample (MAP) line is drawn:\n", + "fig = posterior.distribution()\n", + "fig.show()\n", + "\n", + "# Standalone equivalent (pass ``logp`` to get the best-sample line):\n", + "# fig = plot_distribution(\n", + "# posterior.draws,\n", + "# posterior.param_names,\n", + "# logp=posterior.logp,\n", + "# return_figure=True,\n", + "# )\n", + "# fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e759a2a0", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:43.464801Z", + "iopub.status.busy": "2026-05-29T06:30:43.464801Z", + "iopub.status.idle": "2026-05-29T06:30:43.847435Z", + "shell.execute_reply": "2026-05-29T06:30:43.847435Z" + } + }, + "outputs": [], + "source": [ + "# ---- Corner plot ------------------------------------------------------------\n", + "# Pairwise correlations: marginal density on the diagonal, scatter samples\n", + "# and 2-D contours on the lower triangle. Mirrors the \"Corner Plot\" sub-tab.\n", + "\n", + "fig = plot_corner(posterior.draws, posterior.param_names)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "593f5ed3", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:43.852778Z", + "iopub.status.busy": "2026-05-29T06:30:43.852778Z", + "iopub.status.idle": "2026-05-29T06:30:43.905089Z", + "shell.execute_reply": "2026-05-29T06:30:43.905089Z" + } + }, + "outputs": [], + "source": [ + "# ---- Trace plot -------------------------------------------------------------\n", + "# Per-chain trace (left column) and marginal histogram (right column).\n", + "# Mirrors the \"Traces\" sub-tab in the EasyReflectometryApp.\n", + "\n", + "fig = plot_trace(posterior.draws, posterior.param_names, return_figure=True)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3049e68a", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:43.906601Z", + "iopub.status.busy": "2026-05-29T06:30:43.906601Z", + "iopub.status.idle": "2026-05-29T06:30:43.912231Z", + "shell.execute_reply": "2026-05-29T06:30:43.911707Z" + } + }, + "outputs": [], + "source": [ + "# ---- Credible intervals -----------------------------------------------------\n", + "# Equal-tailed 95 % credible intervals for each parameter.\n", + "\n", + "ci_95 = posterior.credible_interval(alpha=0.95)\n", + "print('95 % credible intervals:')\n", + "for name, (lo, hi) in ci_95.items():\n", + " print(f' {name:<30s} [{lo:.4f}, {hi:.4f}]')\n", + "\n", + "# You can request narrower intervals too:\n", + "ci_50 = posterior.credible_interval(alpha=0.50)\n", + "print('\\n50 % credible intervals:')\n", + "for name, (lo, hi) in ci_50.items():\n", + " print(f' {name:<30s} [{lo:.4f}, {hi:.4f}]')\n", + "\n", + "# Standalone equivalent:\n", + "# ci = credible_intervals(posterior.draws, posterior.param_names, alpha=0.95)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "806bf47a", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:43.913735Z", + "iopub.status.busy": "2026-05-29T06:30:43.913735Z", + "iopub.status.idle": "2026-05-29T06:30:44.004052Z", + "shell.execute_reply": "2026-05-29T06:30:44.004052Z" + } + }, + "outputs": [], + "source": [ + "# ---- Pairwise focus: thickness vs SLD ---------------------------------------\n", + "# A 2-parameter corner plot zooms in on the joint posterior for a specific\n", + "# pair. This is the same view the EasyReflectometryApp's \"2D Heatmap\"\n", + "# sub-tab uses to inspect parameter degeneracies.\n", + "\n", + "\n", + "params_of_interest = ['Layer_1_ThicknessParameter_0', 'Material_1_SldParameter_0']\n", + "idx = [posterior.param_names.index(p) for p in params_of_interest]\n", + "subset_draws = np.asarray(posterior.draws)[:, idx]\n", + "\n", + "fig = plot_corner(subset_draws, params_of_interest)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34e3cc3e", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:44.006603Z", + "iopub.status.busy": "2026-05-29T06:30:44.006603Z", + "iopub.status.idle": "2026-05-29T06:30:44.010758Z", + "shell.execute_reply": "2026-05-29T06:30:44.010226Z" + } + }, + "outputs": [], + "source": [ + "# ---- Gelman-Rubin R‑hat convergence diagnostic ------------------------------\n", + "# Requires ``arviz`` and at least 2 chains. Values close to 1.0 indicate\n", + "# good convergence.\n", + "\n", + "try:\n", + " rhat = posterior.gelman_rubin()\n", + " print('Gelman-Rubin R‑hat:')\n", + " for name, r in rhat.items():\n", + " flag = ' ✓' if r < 1.1 else ' ⚠'\n", + " print(f' {name:<30s} R̂ = {r:.3f}{flag}')\n", + "except ValueError:\n", + " print(\n", + " 'Skipped: Gelman-Rubin R‑hat requires at least 2 chains. '\n", + " 'Run with multiple DREAM populations to obtain multi-chain draws.'\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7e5816e", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:44.012760Z", + "iopub.status.busy": "2026-05-29T06:30:44.012760Z", + "iopub.status.idle": "2026-05-29T06:30:45.165079Z", + "shell.execute_reply": "2026-05-29T06:30:45.165079Z" + } + }, + "outputs": [], + "source": [ + "# ---- Posterior-predictive reflectivity --------------------------------------\n", + "# Propagate parameter uncertainty through the model to obtain median\n", + "# reflectivity and 95 % credible band.\n", + "\n", + "r_median, r_lower, r_upper = posterior_predictive_reflectivity(\n", + " posterior.draws,\n", + " posterior.param_names,\n", + " model,\n", + " qz,\n", + " n_samples=200,\n", + ")\n", + "\n", + "plt.figure(figsize=(9, 6))\n", + "plt.semilogy(qz, r_data, 'o', label='Data', alpha=0.6)\n", + "plt.semilogy(qz, r_median, '-', color='tab:orange', label='Posterior median')\n", + "plt.fill_between(\n", + " qz,\n", + " r_lower,\n", + " r_upper,\n", + " color='tab:orange',\n", + " alpha=0.3,\n", + " label='95 % credible interval',\n", + ")\n", + "plt.xlabel('Q / Å⁻¹')\n", + "plt.ylabel('Reflectivity')\n", + "plt.title('Bayesian Posterior-Predictive Check')\n", + "plt.legend()\n", + "plt.grid(True, alpha=0.3)\n", + "plt.show()\n", + "\n", + "print('The 95 % credible interval captures parameter uncertainty propagated through the model.')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef27b8ec", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:45.166642Z", + "iopub.status.busy": "2026-05-29T06:30:45.166642Z", + "iopub.status.idle": "2026-05-29T06:30:45.413146Z", + "shell.execute_reply": "2026-05-29T06:30:45.413146Z" + } + }, + "outputs": [], + "source": [ + "# ---- Posterior-predictive SLD profile ---------------------------------------\n", + "# The same idea applied to the scattering-length-density profile.\n", + "\n", + "z, sld_median, sld_lower, sld_upper = posterior_predictive_sld_profile(\n", + " posterior.draws,\n", + " posterior.param_names,\n", + " model,\n", + " n_samples=200,\n", + ")\n", + "\n", + "plt.figure(figsize=(8, 4))\n", + "plt.plot(z, sld_median, label='Posterior median SLD')\n", + "plt.fill_between(\n", + " z,\n", + " sld_lower,\n", + " sld_upper,\n", + " alpha=0.3,\n", + " label='95 % credible interval',\n", + ")\n", + "plt.xlabel('z / Å')\n", + "plt.ylabel('SLD / 10⁻⁶ Å⁻²')\n", + "plt.title('SLD Profile with Bayesian Uncertainty')\n", + "plt.legend()\n", + "plt.grid(True, alpha=0.3)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37e78b4e", + "metadata": { + "execution": { + "iopub.execute_input": "2026-05-29T06:30:45.415149Z", + "iopub.status.busy": "2026-05-29T06:30:45.415149Z", + "iopub.status.idle": "2026-05-29T06:30:45.419700Z", + "shell.execute_reply": "2026-05-29T06:30:45.419700Z" + } + }, + "outputs": [], + "source": [ + "# ---- Summary ----------------------------------------------------------------\n", + "print('―' * 60)\n", + "print('Bayesian analysis complete!')\n", + "print('―' * 60)\n", + "print()\n", + "print('API surface demonstrated:')\n", + "print(' MultiFitter.mcmc_sample(data, samples=, burn=, thin=)')\n", + "print(' PosteriorResults(draws, param_names, logp=, sampler_state=)')\n", + "print(' .summary() — formatted parameter table')\n", + "print(' .distribution() — per-parameter marginal Plotly figure')\n", + "print(' .corner() — pairwise correlation Plotly figure')\n", + "print(' .trace() — MCMC chain trace plot')\n", + "print(' .credible_interval(alpha) — equal-tailed credible intervals')\n", + "print(' .gelman_rubin() — R̂ convergence diagnostic')\n", + "print()\n", + "print(' Standalone functions (work on raw dict; the plot helpers return')\n", + "print(' the same interactive Plotly figures as the App):')\n", + "print(' posterior_summary(draws, names)')\n", + "print(' plot_distribution(draws, names, logp=, return_figure=True)')\n", + "print(' plot_corner(draws, names)')\n", + "print(' plot_trace(draws, names, return_figure=True)')\n", + "print(' credible_intervals(draws, names, alpha)')\n", + "print(' posterior_predictive_reflectivity(draws, names, model, q, n)')\n", + "print(' posterior_predictive_sld_profile(draws, names, model, n)')\n", + "print()\n", + "print('The high-level API provides clean, safe access to BUMPS DREAM sampling.')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "era", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/docs/tutorials/advancedfitting/example.ort b/docs/docs/tutorials/advancedfitting/example.ort new file mode 100644 index 00000000..968fa7bb --- /dev/null +++ b/docs/docs/tutorials/advancedfitting/example.ort @@ -0,0 +1,448 @@ +# # ORSO reflectivity data file | 0.1 standard | YAML encoding | https://www.reflectometry.org/ +# data_source: +# owner: +# name: Andrew Nelson +# affiliation: ANSTO +# contact: Andrew.Nelson@ansto.gov.au +# experiment: +# facility: ANSTO +# start_date: 2021-05-12 +# title: Example data file from refnx docs +# instrument: platypus +# probe: neutron +# sample: +# name: Polymer Film +# category: solid / liquid +# composition: Si / SiO2 / Film / D2O +# measurement: +# instrument_settings: +# wavelength: +# magnitude: 12 +# unit: angstrom +# incident_angle: +# magnitude: 3 +# unit: deg +# data_files: +# - Unknown.nxs +# scheme: angle-dispersive +# reduction: +# software: ess +# timestamp: 2022-01-27T15:33:59+01:00 +# corrections: +# - footprint +# - incident intensity +# - detector efficiency +# columns: +# - {name: Qz, unit: 1/angstrom, dimension: WW transfer} +# - {name: R, dimension: reflectivity} +# - {name: sR, dimension: error-reflectivity} +# - {name: sQz, unit: 1/angstrom, dimension: resolution-WW transfer} +## Qz RQz sR sQz +8.060220000e-03 7.095810000e-01 8.506760000e-02 1.407419648e-04 +8.136620000e-03 8.622810000e-01 1.123700000e-01 1.420996057e-04 +8.263750000e-03 9.086470000e-01 7.900470000e-02 1.443588017e-04 +8.370670000e-03 7.732920000e-01 7.927280000e-02 1.462583099e-04 +8.450330000e-03 1.057970000e+00 1.259590000e-01 1.476732801e-04 +8.530830000e-03 1.015660000e+00 1.132950000e-01 1.491031133e-04 +8.612170000e-03 7.347170000e-01 6.115660000e-02 1.505473850e-04 +8.694370000e-03 7.692160000e-01 6.170580000e-02 1.520069445e-04 +8.777430000e-03 1.115740000e+00 1.127300000e-01 1.534813672e-04 +8.861360000e-03 9.723030000e-01 8.971600000e-02 1.549710776e-04 +8.946160000e-03 7.512140000e-01 5.493930000e-02 1.564760759e-04 +9.031850000e-03 7.976490000e-01 5.671220000e-02 1.579963619e-04 +9.118440000e-03 9.221890000e-01 6.858410000e-02 1.595327850e-04 +9.205930000e-03 9.757550000e-01 7.293950000e-02 1.610844959e-04 +9.294320000e-03 8.195040000e-01 5.216170000e-02 1.626523440e-04 +9.383640000e-03 7.883200000e-01 4.794730000e-02 1.642367538e-04 +9.473890000e-03 7.947010000e-01 4.602240000e-02 1.658368761e-04 +9.565080000e-03 8.744000000e-01 5.151640000e-02 1.674535601e-04 +9.657210000e-03 8.396620000e-01 4.742850000e-02 1.690872306e-04 +9.750300000e-03 8.008720000e-01 4.399580000e-02 1.707370382e-04 +9.844360000e-03 1.117100000e+00 7.373300000e-02 1.724042569e-04 +9.939390000e-03 8.884110000e-01 4.954100000e-02 1.740884620e-04 +1.003540000e-02 7.791290000e-01 3.898730000e-02 1.757896536e-04 +1.013240000e-02 7.999680000e-01 3.899740000e-02 1.775086809e-04 +1.023040000e-02 8.431240000e-01 4.159800000e-02 1.792451193e-04 +1.032940000e-02 9.613320000e-01 4.925360000e-02 1.809989689e-04 +1.048680000e-02 8.805440000e-01 2.990830000e-02 1.837851690e-04 +1.063270000e-02 7.557350000e-01 3.208510000e-02 1.863700799e-04 +1.073590000e-02 9.712310000e-01 4.534850000e-02 1.881969711e-04 +1.084010000e-02 8.955490000e-01 3.905420000e-02 1.900425474e-04 +1.094540000e-02 8.625890000e-01 3.580720000e-02 1.919068087e-04 +1.105180000e-02 8.909920000e-01 3.612570000e-02 1.937906045e-04 +1.115930000e-02 9.003480000e-01 3.679240000e-02 1.956930853e-04 +1.126790000e-02 8.459270000e-01 3.218810000e-02 1.976151006e-04 +1.137760000e-02 9.431520000e-01 3.655330000e-02 1.995570749e-04 +1.148840000e-02 9.956310000e-01 3.901160000e-02 2.015185836e-04 +1.160040000e-02 9.695940000e-01 3.636230000e-02 2.034996267e-04 +1.171350000e-02 9.051810000e-01 3.204100000e-02 2.055014781e-04 +1.182780000e-02 8.933810000e-01 3.061190000e-02 2.075232887e-04 +1.194330000e-02 9.196020000e-01 3.146770000e-02 2.095659076e-04 +1.205990000e-02 9.189980000e-01 3.060970000e-02 2.116293349e-04 +1.217770000e-02 7.810560000e-01 2.355420000e-02 2.137135706e-04 +1.229680000e-02 8.649150000e-01 2.720250000e-02 2.158190394e-04 +1.241700000e-02 8.435160000e-01 2.550150000e-02 2.179457412e-04 +1.253850000e-02 9.984180000e-01 3.197220000e-02 2.200945253e-04 +1.266120000e-02 8.812600000e-01 2.602730000e-02 2.222645425e-04 +1.278520000e-02 8.835690000e-01 2.558620000e-02 2.244570667e-04 +1.291050000e-02 9.376700000e-01 2.746510000e-02 2.266716733e-04 +1.303700000e-02 1.019200000e+00 3.051070000e-02 2.289087870e-04 +1.316480000e-02 8.455260000e-01 2.262690000e-02 2.311684076e-04 +1.329390000e-02 8.738040000e-01 2.324680000e-02 2.334509599e-04 +1.342430000e-02 8.659530000e-01 2.249060000e-02 2.357568686e-04 +1.355610000e-02 8.779820000e-01 2.244910000e-02 2.380861337e-04 +1.368920000e-02 9.475450000e-01 2.489850000e-02 2.404387551e-04 +1.382370000e-02 8.881540000e-01 2.209620000e-02 2.428155821e-04 +1.395950000e-02 8.913620000e-01 2.181480000e-02 2.452161902e-04 +1.409670000e-02 8.884560000e-01 2.150920000e-02 2.476410039e-04 +1.423530000e-02 9.137170000e-01 2.225860000e-02 2.500908727e-04 +1.437530000e-02 8.103640000e-01 1.882890000e-02 2.525649471e-04 +1.451680000e-02 7.385480000e-01 1.688270000e-02 2.550645011e-04 +1.465970000e-02 6.865100000e-01 1.597420000e-02 2.575891102e-04 +1.480400000e-02 5.822400000e-01 1.350210000e-02 2.601396235e-04 +1.494980000e-02 4.468550000e-01 1.006260000e-02 2.627156166e-04 +1.509700000e-02 3.924610000e-01 9.155490000e-03 2.653175139e-04 +1.524580000e-02 3.205170000e-01 7.319590000e-03 2.679461649e-04 +1.539610000e-02 2.810060000e-01 6.399090000e-03 2.706011448e-04 +1.554790000e-02 2.401000000e-01 5.442390000e-03 2.732828784e-04 +1.570120000e-02 2.208810000e-01 5.024370000e-03 2.759917903e-04 +1.585610000e-02 1.920330000e-01 4.314410000e-03 2.787278805e-04 +1.601260000e-02 1.798490000e-01 4.051590000e-03 2.814919983e-04 +1.617070000e-02 1.600690000e-01 3.562020000e-03 2.842837190e-04 +1.633030000e-02 1.531290000e-01 3.467770000e-03 2.871038920e-04 +1.649160000e-02 1.342200000e-01 3.016000000e-03 2.899525174e-04 +1.665450000e-02 1.283300000e-01 2.888530000e-03 2.928300196e-04 +1.681900000e-02 1.247940000e-01 2.861820000e-03 2.957363988e-04 +1.698530000e-02 1.091270000e-01 2.483100000e-03 2.986720796e-04 +1.715320000e-02 1.044290000e-01 2.353920000e-03 3.016374867e-04 +1.732280000e-02 9.468300000e-02 2.091620000e-03 3.046326200e-04 +1.758810000e-02 8.969110000e-02 1.439380000e-03 3.093191777e-04 +1.784190000e-02 8.091440000e-02 1.872780000e-03 3.138010489e-04 +1.801850000e-02 7.465440000e-02 1.714220000e-03 3.169189092e-04 +1.819680000e-02 7.036610000e-02 1.634230000e-03 3.200686191e-04 +1.837700000e-02 6.904450000e-02 1.605300000e-03 3.232497539e-04 +1.855890000e-02 6.270550000e-02 1.461460000e-03 3.264631629e-04 +1.874270000e-02 5.939150000e-02 1.400070000e-03 3.297088462e-04 +1.892840000e-02 5.754770000e-02 1.360950000e-03 3.329872283e-04 +1.911590000e-02 5.138330000e-02 1.226680000e-03 3.362987340e-04 +1.930540000e-02 4.922670000e-02 1.178240000e-03 3.396437879e-04 +1.949670000e-02 4.521740000e-02 1.079620000e-03 3.430219654e-04 +1.969000000e-02 4.245560000e-02 1.022250000e-03 3.464349651e-04 +1.988520000e-02 4.126130000e-02 9.947810000e-04 3.498819376e-04 +2.008240000e-02 3.523330000e-02 8.777900000e-04 3.533637323e-04 +2.028150000e-02 3.352710000e-02 8.367470000e-04 3.568803492e-04 +2.048270000e-02 3.326840000e-02 8.339590000e-04 3.604326376e-04 +2.068590000e-02 3.166440000e-02 7.898860000e-04 3.640210222e-04 +2.089120000e-02 2.916000000e-02 7.496130000e-04 3.676450784e-04 +2.109850000e-02 2.652010000e-02 7.063830000e-04 3.713060800e-04 +2.130800000e-02 2.518290000e-02 6.713890000e-04 3.750036024e-04 +2.151950000e-02 2.387570000e-02 6.426930000e-04 3.787384951e-04 +2.173310000e-02 2.289290000e-02 6.330680000e-04 3.825111825e-04 +2.194900000e-02 2.086460000e-02 5.931280000e-04 3.863216648e-04 +2.216690000e-02 2.087710000e-02 5.920100000e-04 3.901703665e-04 +2.238710000e-02 1.822280000e-02 5.292050000e-04 3.940581370e-04 +2.260950000e-02 1.773460000e-02 5.251520000e-04 3.979849764e-04 +2.283410000e-02 1.587140000e-02 4.818770000e-04 4.019513092e-04 +2.306100000e-02 1.432550000e-02 4.516190000e-04 4.059575601e-04 +2.329020000e-02 1.427760000e-02 4.522490000e-04 4.100041538e-04 +2.352170000e-02 1.266240000e-02 4.198450000e-04 4.140919397e-04 +2.375550000e-02 1.221280000e-02 4.137860000e-04 4.182204929e-04 +2.399170000e-02 1.046080000e-02 3.745320000e-04 4.223906630e-04 +2.423020000e-02 1.061330000e-02 3.810520000e-04 4.266016005e-04 +2.447120000e-02 9.879030000e-03 3.641280000e-04 4.308567027e-04 +2.471450000e-02 8.372030000e-03 3.313930000e-04 4.351542710e-04 +2.496030000e-02 7.670480000e-03 3.077050000e-04 4.394943054e-04 +2.520860000e-02 7.344890000e-03 3.049780000e-04 4.438810525e-04 +2.545940000e-02 6.798650000e-03 2.898680000e-04 4.483102657e-04 +2.571270000e-02 5.916300000e-03 2.671780000e-04 4.527819450e-04 +2.596850000e-02 5.344980000e-03 2.515360000e-04 4.573003369e-04 +2.622690000e-02 5.122650000e-03 2.474120000e-04 4.618611950e-04 +2.648800000e-02 4.750310000e-03 2.379530000e-04 4.664730124e-04 +2.675160000e-02 4.307150000e-03 2.238500000e-04 4.711272958e-04 +2.701790000e-02 4.018170000e-03 2.200510000e-04 4.758325386e-04 +2.728680000e-02 3.539150000e-03 2.046530000e-04 4.805802475e-04 +2.755850000e-02 3.818190000e-03 2.079440000e-04 4.853789156e-04 +2.783290000e-02 2.864750000e-03 1.819210000e-04 4.902285431e-04 +2.811000000e-02 2.795800000e-03 1.766910000e-04 4.951206367e-04 +2.839000000e-02 2.621500000e-03 1.750020000e-04 5.000679362e-04 +2.867270000e-02 2.484770000e-03 1.694560000e-04 5.050619484e-04 +2.895830000e-02 2.420090000e-03 1.709250000e-04 5.101069199e-04 +2.924670000e-02 2.359260000e-03 1.700600000e-04 5.151986041e-04 +2.953810000e-02 1.978560000e-03 1.600210000e-04 5.203454942e-04 +2.983230000e-02 1.947200000e-03 1.582820000e-04 5.255475902e-04 +3.012960000e-02 1.735930000e-03 1.527310000e-04 5.307963989e-04 +3.042980000e-02 1.894590000e-03 1.603050000e-04 5.361004136e-04 +3.073300000e-02 1.696680000e-03 1.525740000e-04 5.414596341e-04 +3.103920000e-02 1.793690000e-03 1.592450000e-04 5.468698140e-04 +3.134860000e-02 1.786860000e-03 1.552020000e-04 5.523351998e-04 +3.166100000e-02 1.872010000e-03 1.583950000e-04 5.578557915e-04 +3.197660000e-02 1.688180000e-03 1.499840000e-04 5.634315891e-04 +3.229530000e-02 1.732370000e-03 1.543250000e-04 5.690625926e-04 +3.261730000e-02 1.537600000e-03 1.453960000e-04 5.747530487e-04 +3.294240000e-02 1.541340000e-03 1.497560000e-04 5.804987107e-04 +3.327080000e-02 1.700330000e-03 1.572080000e-04 5.863038252e-04 +3.360260000e-02 2.142240000e-03 1.728870000e-04 5.921683922e-04 +3.393760000e-02 1.944020000e-03 1.686890000e-04 5.980924118e-04 +3.422050000e-02 1.914000000e-03 1.077140000e-04 6.019483327e-04 +3.466450000e-02 1.986410000e-03 1.438280000e-04 6.103523719e-04 +3.502190000e-02 1.849740000e-03 1.279740000e-04 6.165099550e-04 +3.538500000e-02 1.932640000e-03 1.227080000e-04 6.227354838e-04 +3.571620000e-02 2.188990000e-03 1.495980000e-04 6.288506008e-04 +3.607730000e-02 2.314320000e-03 1.503450000e-04 6.351568151e-04 +3.646770000e-02 1.831770000e-03 1.041590000e-04 6.416328939e-04 +3.682630000e-02 1.797150000e-03 1.012920000e-04 6.480155472e-04 +3.716160000e-02 2.278740000e-03 1.417330000e-04 6.543599810e-04 +3.754210000e-02 2.183390000e-03 1.294600000e-04 6.609379784e-04 +3.794040000e-02 1.799000000e-03 9.624980000e-05 6.676221409e-04 +3.831280000e-02 1.828080000e-03 9.734640000e-05 6.742680840e-04 +3.868400000e-02 1.949850000e-03 1.082600000e-04 6.809692330e-04 +3.906920000e-02 2.042140000e-03 1.122450000e-04 6.877680540e-04 +3.947340000e-02 1.659460000e-03 8.395540000e-05 6.946772869e-04 +3.986330000e-02 1.620310000e-03 8.073380000e-05 7.016035062e-04 +4.026580000e-02 1.588620000e-03 7.617690000e-05 7.086189042e-04 +4.066080000e-02 1.582510000e-03 7.829120000e-05 7.156810150e-04 +4.107010000e-02 1.429900000e-03 7.034450000e-05 7.228323046e-04 +4.147810000e-02 1.336120000e-03 6.498820000e-05 7.300472933e-04 +4.187440000e-02 1.721900000e-03 9.200060000e-05 7.373174879e-04 +4.230490000e-02 1.404890000e-03 6.788170000e-05 7.446980943e-04 +4.273170000e-02 1.146480000e-03 5.315150000e-05 7.521381533e-04 +4.315460000e-02 1.030130000e-03 4.872800000e-05 7.596504046e-04 +4.358350000e-02 1.018640000e-03 4.851630000e-05 7.672348483e-04 +4.401550000e-02 1.060250000e-03 5.148880000e-05 7.748999775e-04 +4.445490000e-02 9.115610000e-04 4.517670000e-05 7.826415457e-04 +4.489830000e-02 7.795360000e-04 3.746760000e-05 7.904553063e-04 +4.534700000e-02 5.957570000e-04 2.867780000e-05 7.983539991e-04 +4.579470000e-02 6.476450000e-04 3.286690000e-05 8.063333774e-04 +4.625120000e-02 5.268390000e-04 2.666210000e-05 8.143891946e-04 +4.671240000e-02 4.365460000e-04 2.240950000e-05 8.225299441e-04 +4.717830000e-02 3.696050000e-04 1.929650000e-05 8.307471325e-04 +4.764690000e-02 3.315640000e-04 1.808550000e-05 8.390577463e-04 +4.812080000e-02 2.545840000e-04 1.440620000e-05 8.474405525e-04 +4.859940000e-02 2.090800000e-04 1.312430000e-05 8.559167841e-04 +4.908280000e-02 1.929370000e-04 1.261590000e-05 8.644779478e-04 +4.957100000e-02 1.309220000e-04 9.992220000e-06 8.731240437e-04 +5.006400000e-02 1.098230000e-04 9.080510000e-06 8.818635651e-04 +5.056190000e-02 9.565480000e-05 8.370090000e-06 8.906880186e-04 +5.106550000e-02 7.925720000e-05 7.699130000e-06 8.995974043e-04 +5.157340000e-02 7.956050000e-05 6.898560000e-06 9.086044619e-04 +5.208640000e-02 7.224950000e-05 6.102730000e-06 9.177006984e-04 +5.260450000e-02 7.825130000e-05 6.391360000e-06 9.268903603e-04 +5.312790000e-02 8.637120000e-05 6.561860000e-06 9.361734476e-04 +5.365650000e-02 1.331620000e-04 8.789840000e-06 9.455499603e-04 +5.419050000e-02 1.436320000e-04 8.178840000e-06 9.550241449e-04 +5.472980000e-02 1.586820000e-04 8.565340000e-06 9.645917550e-04 +5.527450000e-02 1.900070000e-04 9.755240000e-06 9.742612837e-04 +5.582470000e-02 2.354200000e-04 1.141720000e-05 9.840284844e-04 +5.638040000e-02 2.339320000e-04 1.034520000e-05 9.938933571e-04 +5.694170000e-02 2.433900000e-04 1.059550000e-05 1.003855902e-03 +5.750870000e-02 2.708580000e-04 1.125130000e-05 1.013924612e-03 +5.808130000e-02 3.109660000e-04 1.233550000e-05 1.024095240e-03 +5.865970000e-02 3.483270000e-04 1.357860000e-05 1.034367788e-03 +5.924390000e-02 3.329570000e-04 1.275590000e-05 1.044750747e-03 +5.983400000e-02 3.546590000e-04 1.322360000e-05 1.055235624e-03 +6.043000000e-02 3.544670000e-04 1.306610000e-05 1.065826667e-03 +6.103190000e-02 3.855150000e-04 1.408930000e-05 1.076523875e-03 +6.164000000e-02 3.325090000e-04 1.201760000e-05 1.087335742e-03 +6.225410000e-02 3.330870000e-04 1.197150000e-05 1.098253773e-03 +6.287440000e-02 3.303070000e-04 1.197230000e-05 1.109286464e-03 +6.350090000e-02 3.224690000e-04 1.162910000e-05 1.120433812e-03 +6.413370000e-02 2.744620000e-04 9.948790000e-06 1.131691573e-03 +6.477280000e-02 2.792430000e-04 1.025370000e-05 1.143063992e-03 +6.541840000e-02 2.389380000e-04 8.960850000e-06 1.154555315e-03 +6.607040000e-02 2.330280000e-04 8.726650000e-06 1.166165544e-03 +6.672900000e-02 1.863430000e-04 7.236140000e-06 1.177890432e-03 +6.739420000e-02 1.649490000e-04 6.619500000e-06 1.189738471e-03 +6.806600000e-02 1.332440000e-04 5.541570000e-06 1.201709662e-03 +6.874460000e-02 1.153760000e-04 4.971620000e-06 1.213799758e-03 +6.943000000e-02 8.250330000e-05 3.951150000e-06 1.226017252e-03 +7.012230000e-02 6.719230000e-05 3.570180000e-06 1.238357898e-03 +7.082150000e-02 5.033220000e-05 2.926230000e-06 1.250825942e-03 +7.152780000e-02 3.336120000e-05 2.509700000e-06 1.263421384e-03 +7.224110000e-02 2.290520000e-05 2.116380000e-06 1.276148471e-03 +7.293380000e-02 1.879440000e-05 1.860530000e-06 1.288068702e-03 +7.366830000e-02 1.553440000e-05 1.798210000e-06 1.301292643e-03 +7.440150000e-02 1.824520000e-05 1.951840000e-06 1.314359459e-03 +7.514050000e-02 2.235620000e-05 1.801000000e-06 1.327506960e-03 +7.587210000e-02 2.773620000e-05 1.890140000e-06 1.340293500e-03 +7.664020000e-02 3.931010000e-05 2.300950000e-06 1.354192651e-03 +7.739640000e-02 4.596690000e-05 2.332400000e-06 1.367582209e-03 +7.810610000e-02 5.541310000e-05 2.459260000e-06 1.379328330e-03 +7.886820000e-02 6.726050000e-05 2.729570000e-06 1.392692408e-03 +7.979530000e-02 7.650640000e-05 2.773090000e-06 1.409143772e-03 +8.072890000e-02 7.794720000e-05 2.857410000e-06 1.425518696e-03 +8.153340000e-02 8.505420000e-05 2.990400000e-06 1.439910454e-03 +8.233180000e-02 9.685690000e-05 3.222700000e-06 1.454408377e-03 +8.316050000e-02 9.462400000e-05 3.166210000e-06 1.469122877e-03 +8.402520000e-02 8.585640000e-05 2.824460000e-06 1.484058201e-03 +8.486480000e-02 8.101440000e-05 2.662540000e-06 1.499057224e-03 +8.573420000e-02 7.655920000e-05 2.549780000e-06 1.514268578e-03 +8.655530000e-02 7.385430000e-05 2.485840000e-06 1.529496917e-03 +8.743720000e-02 6.249710000e-05 2.190920000e-06 1.545009780e-03 +8.831630000e-02 5.495430000e-05 2.001270000e-06 1.560658534e-03 +8.911080000e-02 5.694540000e-05 2.081580000e-06 1.576247836e-03 +9.004160000e-02 4.229200000e-05 1.729710000e-06 1.592304265e-03 +9.095460000e-02 3.367540000e-05 1.458910000e-06 1.608462612e-03 +9.185040000e-02 2.545640000e-05 1.249630000e-06 1.624727124e-03 +9.274350000e-02 2.092210000e-05 1.159760000e-06 1.641140268e-03 +9.362890000e-02 1.531120000e-05 1.060140000e-06 1.657689303e-03 +9.455270000e-02 1.265650000e-05 9.577530000e-07 1.674480395e-03 +9.551780000e-02 9.331240000e-06 8.621390000e-07 1.691509297e-03 +9.647710000e-02 8.901520000e-06 7.828970000e-07 1.708691077e-03 +9.741890000e-02 1.079150000e-05 8.938470000e-07 1.725991763e-03 +9.842590000e-02 1.213680000e-05 9.113080000e-07 1.743589710e-03 +9.942010000e-02 1.540800000e-05 9.077770000e-07 1.761323549e-03 +1.004250000e-01 1.938030000e-05 9.602530000e-07 1.779248486e-03 +1.014340000e-01 2.091160000e-05 1.040890000e-06 1.797347534e-03 +1.024990000e-01 2.519250000e-05 1.078370000e-06 1.815722611e-03 +1.034980000e-01 2.818800000e-05 1.132170000e-06 1.834144401e-03 +1.045460000e-01 2.998100000e-05 1.178530000e-06 1.852837973e-03 +1.056080000e-01 3.056280000e-05 1.150490000e-06 1.871735383e-03 +1.066820000e-01 2.819030000e-05 1.099070000e-06 1.890832384e-03 +1.077580000e-01 2.692630000e-05 1.037400000e-06 1.910111989e-03 +1.088310000e-01 2.541920000e-05 1.012560000e-06 1.929574198e-03 +1.099160000e-01 2.282700000e-05 9.367100000e-07 1.949244491e-03 +1.110400000e-01 1.769170000e-05 7.904500000e-07 1.969169580e-03 +1.121170000e-01 1.547510000e-05 7.625400000e-07 1.989209328e-03 +1.132440000e-01 1.172580000e-05 6.688050000e-07 2.009529352e-03 +1.143190000e-01 1.050270000e-05 6.598050000e-07 2.029959788e-03 +1.154640000e-01 8.121530000e-06 5.847030000e-07 2.050708720e-03 +1.166450000e-01 4.988840000e-06 5.267190000e-07 2.071720941e-03 +1.177620000e-01 4.909990000e-06 5.360960000e-07 2.092830835e-03 +1.189250000e-01 5.304340000e-06 5.240840000e-07 2.114229497e-03 +1.201290000e-01 5.689050000e-06 4.912340000e-07 2.135895696e-03 +1.213460000e-01 6.444710000e-06 5.061070000e-07 2.157799706e-03 +1.225860000e-01 7.456190000e-06 5.058030000e-07 2.179954265e-03 +1.238230000e-01 8.248420000e-06 5.025600000e-07 2.202325401e-03 +1.250910000e-01 1.067490000e-05 5.845390000e-07 2.224964074e-03 +1.263610000e-01 1.131620000e-05 5.722280000e-07 2.247827816e-03 +1.276430000e-01 1.104400000e-05 5.762550000e-07 2.270937863e-03 +1.289320000e-01 1.062580000e-05 5.655340000e-07 2.294294212e-03 +1.302100000e-01 9.337660000e-06 5.254720000e-07 2.317858646e-03 +1.315470000e-01 8.922800000e-06 5.000680000e-07 2.341754314e-03 +1.328540000e-01 6.436110000e-06 4.446880000e-07 2.365841081e-03 +1.341620000e-01 6.181130000e-06 4.556250000e-07 2.390178397e-03 +1.355150000e-01 4.685680000e-06 4.034780000e-07 2.414821469e-03 +1.368240000e-01 4.667540000e-06 3.809290000e-07 2.439659885e-03 +1.382040000e-01 4.262500000e-06 3.763010000e-07 2.464842276e-03 +1.395890000e-01 3.884300000e-06 3.571580000e-07 2.490292204e-03 +1.409890000e-01 3.699480000e-06 3.796620000e-07 2.516022408e-03 +1.424300000e-01 3.659930000e-06 3.543380000e-07 2.542066861e-03 +1.438510000e-01 4.559390000e-06 3.665690000e-07 2.568357617e-03 +1.452630000e-01 4.580880000e-06 3.470620000e-07 2.594911663e-03 +1.467500000e-01 4.829290000e-06 3.503920000e-07 2.621826671e-03 +1.482250000e-01 4.930920000e-06 3.533300000e-07 2.649009215e-03 +1.497100000e-01 4.781000000e-06 3.612560000e-07 2.676489022e-03 +1.512250000e-01 4.644840000e-06 3.397110000e-07 2.704291571e-03 +1.527360000e-01 4.365080000e-06 3.324590000e-07 2.732374397e-03 +1.542610000e-01 3.807060000e-06 3.253780000e-07 2.760775718e-03 +1.558250000e-01 3.544150000e-06 3.053880000e-07 2.789516767e-03 +1.573660000e-01 2.632690000e-06 2.773550000e-07 2.818538093e-03 +1.589410000e-01 2.129680000e-06 2.570610000e-07 2.847903395e-03 +1.605110000e-01 2.509080000e-06 2.684170000e-07 2.877574452e-03 +1.621370000e-01 2.606260000e-06 2.683540000e-07 2.907627704e-03 +1.637550000e-01 2.467960000e-06 2.618110000e-07 2.937986711e-03 +1.654040000e-01 2.437690000e-06 2.457080000e-07 2.968710928e-03 +1.670350000e-01 2.818460000e-06 2.626350000e-07 2.999740899e-03 +1.687360000e-01 3.201910000e-06 2.677220000e-07 3.031182793e-03 +1.704100000e-01 3.020960000e-06 2.548660000e-07 3.062934688e-03 +1.721190000e-01 2.398550000e-06 2.324640000e-07 3.095064532e-03 +1.738390000e-01 2.458240000e-06 2.385460000e-07 3.127555337e-03 +1.755740000e-01 2.033660000e-06 2.231960000e-07 3.160419844e-03 +1.773360000e-01 1.684040000e-06 2.048280000e-07 3.193666546e-03 +1.790870000e-01 1.293830000e-06 2.007650000e-07 3.227265717e-03 +1.809070000e-01 1.439670000e-06 1.882070000e-07 3.261306534e-03 +1.827150000e-01 1.540200000e-06 1.999980000e-07 3.295708314e-03 +1.845350000e-01 1.338490000e-06 1.864820000e-07 3.330500781e-03 +1.863830000e-01 1.615990000e-06 1.863690000e-07 3.365705170e-03 +1.882470000e-01 1.493470000e-06 1.883860000e-07 3.401317233e-03 +1.901260000e-01 2.059680000e-06 1.920700000e-07 3.437345464e-03 +1.920380000e-01 1.690150000e-06 1.767700000e-07 3.473806849e-03 +1.939540000e-01 1.488370000e-06 1.792740000e-07 3.510675908e-03 +1.959000000e-01 1.403820000e-06 1.747280000e-07 3.547990861e-03 +1.978600000e-01 1.346890000e-06 1.705690000e-07 3.585734722e-03 +1.998450000e-01 9.477100000e-07 1.617790000e-07 3.623937217e-03 +2.018330000e-01 1.089550000e-06 1.735020000e-07 3.662568619e-03 +2.038630000e-01 1.246350000e-06 1.654660000e-07 3.701684134e-03 +2.059040000e-01 1.227370000e-06 1.644900000e-07 3.741254037e-03 +2.079590000e-01 1.168960000e-06 1.584560000e-07 3.781286820e-03 +2.100420000e-01 1.161720000e-06 1.521980000e-07 3.821807963e-03 +2.121400000e-01 1.216890000e-06 1.588540000e-07 3.862808973e-03 +2.142570000e-01 1.317570000e-06 1.546070000e-07 3.904298343e-03 +2.163990000e-01 1.032790000e-06 1.472920000e-07 3.946293059e-03 +2.185700000e-01 1.030660000e-06 1.514730000e-07 3.988805862e-03 +2.207810000e-01 5.945350000e-07 1.511720000e-07 4.031853738e-03 +2.229880000e-01 7.279960000e-07 1.429280000e-07 4.075394220e-03 +2.252160000e-01 7.806310000e-07 1.485250000e-07 4.119465528e-03 +2.274670000e-01 1.063390000e-06 1.499300000e-07 4.164076155e-03 +2.297410000e-01 6.526970000e-07 1.296680000e-07 4.209234596e-03 +2.320370000e-01 1.074380000e-06 1.484530000e-07 4.254932355e-03 +2.343560000e-01 8.687630000e-07 1.468620000e-07 4.301220393e-03 +2.366980000e-01 9.218680000e-07 1.450820000e-07 4.348060490e-03 +2.390640000e-01 6.471490000e-07 1.368090000e-07 4.395495113e-03 +2.414540000e-01 5.363930000e-07 1.356880000e-07 4.443524261e-03 +2.438670000e-01 6.337170000e-07 1.304030000e-07 4.492147934e-03 +2.463040000e-01 6.292700000e-07 1.365570000e-07 4.541408598e-03 +2.487660000e-01 6.332920000e-07 1.224530000e-07 4.591263788e-03 +2.512530000e-01 1.037050000e-06 1.354090000e-07 4.641713503e-03 +2.537640000e-01 8.252860000e-07 1.431610000e-07 4.692842675e-03 +2.563010000e-01 6.268250000e-07 1.192570000e-07 4.744608839e-03 +2.588630000e-01 5.252590000e-07 1.227410000e-07 4.797054460e-03 +2.614500000e-01 5.218320000e-07 1.309180000e-07 4.850137073e-03 +2.640640000e-01 3.916590000e-07 1.213700000e-07 4.903941609e-03 +2.667030000e-01 4.724390000e-07 1.399730000e-07 4.958425602e-03 +2.693690000e-01 5.595360000e-07 1.391510000e-07 5.013589053e-03 +2.720620000e-01 6.640700000e-07 1.448670000e-07 5.069474428e-03 +2.747820000e-01 4.593780000e-07 1.514660000e-07 5.126081726e-03 +2.775290000e-01 3.669610000e-07 1.435460000e-07 5.183453413e-03 +2.803030000e-01 5.315310000e-07 1.483080000e-07 5.241589490e-03 +2.831050000e-01 4.289140000e-07 1.361450000e-07 5.300447491e-03 +2.859350000e-01 5.520060000e-07 1.419830000e-07 5.360112348e-03 +2.887930000e-01 5.702640000e-07 1.529000000e-07 5.420541594e-03 +2.916800000e-01 5.047310000e-07 1.364290000e-07 5.481777696e-03 +2.945960000e-01 6.619230000e-07 1.407930000e-07 5.543863119e-03 +2.975410000e-01 7.601320000e-07 1.607210000e-07 5.606755399e-03 +3.005160000e-01 4.685270000e-07 1.348870000e-07 5.670454534e-03 +3.035200000e-01 4.428600000e-07 1.471340000e-07 5.735087923e-03 +3.065540000e-01 4.899790000e-07 1.404300000e-07 5.800528167e-03 +3.096190000e-01 3.601630000e-07 1.337280000e-07 5.866902666e-03 +3.127140000e-01 2.905630000e-07 1.480620000e-07 5.934168953e-03 +3.158410000e-01 5.199630000e-07 1.515620000e-07 6.002327027e-03 +3.189980000e-01 4.666650000e-07 1.562560000e-07 6.071461822e-03 +3.221870000e-01 3.888830000e-07 1.570110000e-07 6.141530870e-03 +3.254080000e-01 4.467780000e-07 1.555120000e-07 6.212576639e-03 +3.286620000e-01 3.238850000e-07 1.525860000e-07 6.284599127e-03 +3.319470000e-01 3.787360000e-07 1.581800000e-07 6.357640802e-03 +3.352660000e-01 3.881990000e-07 1.539110000e-07 6.431701663e-03 +3.386180000e-01 4.428770000e-07 1.490980000e-07 6.506824176e-03 +3.420030000e-01 2.477870000e-07 1.463210000e-07 6.582965876e-03 +3.454230000e-01 2.857690000e-07 1.351350000e-07 6.660211693e-03 +3.488760000e-01 4.759640000e-07 1.536640000e-07 6.738561630e-03 +3.523640000e-01 4.496390000e-07 1.539560000e-07 6.818015684e-03 +3.558870000e-01 2.471470000e-07 1.443220000e-07 6.898573857e-03 +3.594450000e-01 2.167640000e-07 1.491810000e-07 6.980363546e-03 +3.630390000e-01 5.205850000e-07 1.573690000e-07 7.063257354e-03 +3.666690000e-01 5.246970000e-07 1.545410000e-07 7.147425144e-03 +3.703350000e-01 3.644030000e-07 1.550240000e-07 7.232781985e-03 +3.740370000e-01 4.597520000e-07 1.653080000e-07 7.319370343e-03 +3.777770000e-01 5.359220000e-07 1.820430000e-07 7.407232683e-03 +3.815540000e-01 4.268070000e-07 1.770030000e-07 7.496411472e-03 +3.853690000e-01 4.036660000e-07 1.811100000e-07 7.586906710e-03 +3.892220000e-01 2.554540000e-07 1.597290000e-07 7.678718396e-03 +3.931130000e-01 9.269720000e-08 1.654020000e-07 7.771931464e-03 +3.970440000e-01 1.106720000e-07 1.808880000e-07 7.866503446e-03 +4.010140000e-01 4.521630000e-07 1.731910000e-07 7.962519276e-03 +4.050230000e-01 3.780660000e-07 1.515970000e-07 8.059978953e-03 +4.090730000e-01 3.091360000e-07 1.571950000e-07 8.158924942e-03 +4.131630000e-01 3.417740000e-07 1.448180000e-07 8.259357245e-03 +4.172940000e-01 3.449240000e-07 1.595810000e-07 8.361318327e-03 +4.214660000e-01 2.518400000e-07 1.597570000e-07 8.464850655e-03 +4.256800000e-01 4.017370000e-07 1.538140000e-07 8.569954228e-03 +4.299360000e-01 3.172790000e-07 1.691300000e-07 8.676713978e-03 +4.342350000e-01 5.506310000e-07 1.611420000e-07 8.785087440e-03 +4.385770000e-01 5.085100000e-07 1.649900000e-07 8.895159545e-03 +4.429620000e-01 6.025930000e-07 1.738350000e-07 9.006930294e-03 +4.473910000e-01 4.384540000e-07 1.653500000e-07 9.120484618e-03 +4.518650000e-01 3.387570000e-07 1.876390000e-07 9.235822519e-03 +4.563830000e-01 4.358460000e-07 1.978260000e-07 9.352943995e-03 +4.609460000e-01 3.855790000e-07 1.761430000e-07 9.471933979e-03 +4.655550000e-01 3.834150000e-07 1.884540000e-07 9.592834938e-03 diff --git a/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb b/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb index 02f675ba..1c482386 100644 --- a/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb +++ b/docs/docs/tutorials/advancedfitting/multi_contrast.ipynb @@ -72,14 +72,7 @@ "id": "694b4e5e-2d1a-402e-aa3f-a26cc82f7774", "metadata": {}, "outputs": [], - "source": [ - "file_path = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/advancedfitting/multiple.ort',\n", - " known_hash='241bcb819cdae47fbbb310a99c2456c7332312719496b936a153dc7dee83e62c',\n", - ")\n", - "data = load(file_path)" - ] + "source": "file_path = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/multiple.ort',\n known_hash='241bcb819cdae47fbbb310a99c2456c7332312719496b936a153dc7dee83e62c',\n)\ndata = load(file_path)" }, { "cell_type": "markdown", @@ -562,4 +555,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/docs/docs/tutorials/fitting/material_solvated.ipynb b/docs/docs/tutorials/fitting/material_solvated.ipynb index d393eb34..e64f7f7a 100644 --- a/docs/docs/tutorials/fitting/material_solvated.ipynb +++ b/docs/docs/tutorials/fitting/material_solvated.ipynb @@ -96,14 +96,7 @@ "id": "a95a39dd-d0eb-4029-9dc8-41e6e7918f66", "metadata": {}, "outputs": [], - "source": [ - "file_path = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort',\n", - " known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n", - ")\n", - "data = load(file_path)" - ] + "source": "file_path = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/example.ort',\n known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n)\ndata = load(file_path)" }, { "cell_type": "markdown", @@ -372,4 +365,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/docs/docs/tutorials/fitting/monolayer.ipynb b/docs/docs/tutorials/fitting/monolayer.ipynb index e4a7b06d..a04bba8f 100644 --- a/docs/docs/tutorials/fitting/monolayer.ipynb +++ b/docs/docs/tutorials/fitting/monolayer.ipynb @@ -92,15 +92,7 @@ "id": "e392660e-6f02-4f0b-be86-4c8ea78883e0", "metadata": {}, "outputs": [], - "source": [ - "file_path = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/d70d2o.ort',\n", - " known_hash='3e4750536621be8eec493fa21a287e408d384f29cacb113b71d02690d99f0998',\n", - ")\n", - "data = load(file_path)\n", - "plot(data)" - ] + "source": "file_path = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/d70d2o.ort',\n known_hash='3e4750536621be8eec493fa21a287e408d384f29cacb113b71d02690d99f0998',\n)\ndata = load(file_path)\nplot(data)" }, { "cell_type": "markdown", @@ -489,4 +481,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/docs/docs/tutorials/fitting/repeating.ipynb b/docs/docs/tutorials/fitting/repeating.ipynb index e062ac5d..156a1229 100644 --- a/docs/docs/tutorials/fitting/repeating.ipynb +++ b/docs/docs/tutorials/fitting/repeating.ipynb @@ -98,14 +98,7 @@ "id": "7121c7e9", "metadata": {}, "outputs": [], - "source": [ - "file_path = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/repeating_layers.ort',\n", - " known_hash='a5ffca9fd24f1d362266251723aec7ce9f34f123e39a38dfc4d829c758e6bf90',\n", - ")\n", - "data = load(file_path)" - ] + "source": "file_path = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/repeating_layers.ort',\n known_hash='a5ffca9fd24f1d362266251723aec7ce9f34f123e39a38dfc4d829c758e6bf90',\n)\ndata = load(file_path)" }, { "cell_type": "markdown", @@ -346,4 +339,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/docs/docs/tutorials/fitting/simple_fitting.ipynb b/docs/docs/tutorials/fitting/simple_fitting.ipynb index 8eea570a..27d1e485 100644 --- a/docs/docs/tutorials/fitting/simple_fitting.ipynb +++ b/docs/docs/tutorials/fitting/simple_fitting.ipynb @@ -94,14 +94,7 @@ "id": "7d851064-605c-4f80-a510-197bcdbff2ea", "metadata": {}, "outputs": [], - "source": [ - "file_path = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/fitting/example.ort',\n", - " known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n", - ")\n", - "data = load(file_path)" - ] + "source": "file_path = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/example.ort',\n known_hash='82d0c95c069092279a799a8131ad3710335f601d9f1080754b387f42e407dfab',\n)\ndata = load(file_path)" }, { "cell_type": "markdown", @@ -645,4 +638,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/docs/docs/tutorials/simulation/resolution_functions.ipynb b/docs/docs/tutorials/simulation/resolution_functions.ipynb index 48a6893a..b5bd017e 100644 --- a/docs/docs/tutorials/simulation/resolution_functions.ipynb +++ b/docs/docs/tutorials/simulation/resolution_functions.ipynb @@ -101,27 +101,7 @@ "id": "609174e5-1371-412d-a29f-cb05bfe36df0", "metadata": {}, "outputs": [], - "source": [ - "file_path_0 = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-0.0.ort',\n", - " known_hash='f8a3e7007b83f0de4e2c761134e7d1c55027f0099528bd56f746b50349369f50',\n", - ")\n", - "file_path_1 = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-1.0.ort',\n", - " known_hash='9d81a512cbe45f923806ad307e476b27535614b2e08a2bf0f4559ab608a34f7a',\n", - ")\n", - "file_path_10 = pooch.retrieve(\n", - " # URL to one of Pooch's test files\n", - " url='https://raw.githubusercontent.com/EasyScience/EasyReflectometryLib/master/docs/src/tutorials/simulation/mod_pointwise_two_layer_sample_dq-10.0.ort',\n", - " known_hash='991395c0b6a91bf60c12d234c645143dcac1cab929944fc4e452020d44b787ad',\n", - ")\n", - "dict_reference = {}\n", - "dict_reference['0'] = load(file_path_0)\n", - "dict_reference['1'] = load(file_path_1)\n", - "dict_reference['10'] = load(file_path_10)" - ] + "source": "file_path_0 = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/mod_pointwise_two_layer_sample_dq-0.0.ort',\n known_hash='f8a3e7007b83f0de4e2c761134e7d1c55027f0099528bd56f746b50349369f50',\n)\nfile_path_1 = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/mod_pointwise_two_layer_sample_dq-1.0.ort',\n known_hash='9d81a512cbe45f923806ad307e476b27535614b2e08a2bf0f4559ab608a34f7a',\n)\nfile_path_10 = pooch.retrieve(\n # Fetch test data from the easyscience/reflectometry data repository\n url='https://raw.githubusercontent.com/easyscience/reflectometry/master/data/mod_pointwise_two_layer_sample_dq-10.0.ort',\n known_hash='991395c0b6a91bf60c12d234c645143dcac1cab929944fc4e452020d44b787ad',\n)\ndict_reference = {}\ndict_reference['0'] = load(file_path_0)\ndict_reference['1'] = load(file_path_1)\ndict_reference['10'] = load(file_path_10)" }, { "cell_type": "code", @@ -465,4 +445,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/pixi.lock b/pixi.lock index 0399edad..6b3a38bc 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,4 +1,8 @@ -version: 6 +version: 7 +platforms: +- name: linux-64 +- name: osx-arm64 +- name: win-64 environments: default: channels: @@ -9,36 +13,79 @@ environments: packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -54,7 +101,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -80,42 +126,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -129,16 +147,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -146,18 +160,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -166,9 +175,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -181,177 +188,167 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -367,7 +364,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -393,36 +389,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -436,18 +410,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -455,18 +423,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -475,9 +438,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -490,175 +451,214 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: ./ win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -699,26 +699,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -731,26 +719,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda @@ -758,8 +738,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -768,169 +746,201 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl py-311-env: channels: - url: https://conda.anaconda.org/nodefaults/ @@ -940,34 +950,78 @@ environments: packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -983,7 +1037,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -1009,43 +1062,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -1059,34 +1083,25 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -1095,9 +1110,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -1110,175 +1123,163 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/0b/0615dbedb98f5b32a35a53290fbdc6e22306968109278d7e58df82d7a9f6/numba-0.65.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/1f/227f9cb7edcd3e14ab05928f3db00e9d595c0f269c87bf35f565ce44941b/arviz-0.23.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/8b/88f16936a8e8070a83d36239555227ecd91728f9ef222c5382cda07e0fd6/h5netcdf-1.8.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -1294,7 +1295,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -1320,35 +1320,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -1362,36 +1341,25 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -1400,9 +1368,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -1415,173 +1381,209 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/4b/d3c79495dee4831b8bebca2790e72cb90f0c5849c940570a7c7e5b70b952/chardet-7.4.3-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/0b/b9d1911cfefa61399821dfb37f486d83e0f42630a8d12f7194270c417002/llvmlite-0.47.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/1f/227f9cb7edcd3e14ab05928f3db00e9d595c0f269c87bf35f565ce44941b/arviz-0.23.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/8b/88f16936a8e8070a83d36239555227ecd91728f9ef222c5382cda07e0fd6/h5netcdf-1.8.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -1622,25 +1624,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -1653,25 +1644,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda @@ -1679,8 +1662,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -1689,169 +1670,198 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/1f/227f9cb7edcd3e14ab05928f3db00e9d595c0f269c87bf35f565ce44941b/arviz-0.23.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/8b/88f16936a8e8070a83d36239555227ecd91728f9ef222c5382cda07e0fd6/h5netcdf-1.8.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl py-313-env: channels: - url: https://conda.anaconda.org/nodefaults/ @@ -1861,36 +1871,79 @@ environments: packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -1906,7 +1959,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -1932,42 +1984,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -1981,16 +2005,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -1998,18 +2018,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -2018,9 +2033,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -2033,177 +2046,167 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -2219,7 +2222,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda @@ -2245,36 +2247,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -2288,18 +2268,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -2307,18 +2281,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -2327,9 +2296,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -2342,175 +2309,214 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: ./ win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -2551,26 +2557,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -2583,26 +2577,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda @@ -2610,8 +2596,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -2620,207 +2604,272 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: . + - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz - - pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl - - pypi: ./ - user: - channels: - - url: https://conda.anaconda.org/nodefaults/ - - url: https://conda.anaconda.org/conda-forge/ + - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl + user: + channels: + - url: https://conda.anaconda.org/nodefaults/ + - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py313h07c4f96_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -2861,33 +2910,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -2901,16 +2931,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -2918,18 +2944,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -2938,9 +2959,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -2953,138 +2972,127 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/f5/038741f5e747a5f6ea3e72487211579d8cbea5eb9827a9cbd61d0108c4bd/sqlalchemy-2.0.49-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/cd/f5/038741f5e747a5f6ea3e72487211579d8cbea5eb9827a9cbd61d0108c4bd/sqlalchemy-2.0.49-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -3125,28 +3133,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -3160,18 +3154,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda @@ -3179,18 +3167,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -3199,9 +3182,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda @@ -3214,136 +3195,163 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl win-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda @@ -3384,25 +3392,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 @@ -3415,26 +3412,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda @@ -3442,8 +3431,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda @@ -3452,128 +3439,157 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/6b/6c02f55c2ce2f137ccca0986be7dd89bea31d5bee4346b4377fa3b8586df/ncrystal_core-4.4.2-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda build_number: 20 @@ -3589,216 +3605,15 @@ packages: purls: [] size: 28948 timestamp: 1770939786096 -- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 - md5: aaa2a381ccc56eac91d63b6c1240312f +- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda + sha256: b81f852f13a1d148f6ad7e2a29ab375eb1558b73c9bfa38792d98ea7fb414cff + md5: 6e36e9d2b535c3fbe2e093108df26695 depends: - - cpython - - python-gil - license: MIT - license_family: MIT - purls: [] - size: 8191 - timestamp: 1744137672556 -- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - name: aiohappyeyeballs - version: 2.6.1 - sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: aiohttp - version: 3.13.5 - sha256: 3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl - name: aiohttp - version: 3.13.5 - sha256: e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl - name: aiohttp - version: 3.13.5 - sha256: a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl - name: aiohttp - version: 3.13.5 - sha256: 69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl - name: aiohttp - version: 3.13.5 - sha256: d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: aiohttp - version: 3.13.5 - sha256: 3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - name: aiosignal - version: 1.4.0 - sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e - requires_dist: - - frozenlist>=1.1.0 - - typing-extensions>=4.2 ; python_full_version < '3.13' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl - name: annotated-doc - version: 0.0.4 - sha256: 571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 - md5: 2934f256a8acfe48f6ebb4fce6cde29c - depends: - - python >=3.9 - - typing-extensions >=4.0.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/annotated-types?source=hash-mapping - size: 18074 - timestamp: 1733247158254 -- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - sha256: f09aed24661cd45ba54a43772504f05c0698248734f9ae8cd289d314ac89707e - md5: af2df4b9108808da3dc76710fe50eae2 - depends: - - exceptiongroup >=1.0.2 - - idna >=2.8 - - python >=3.10 - - typing_extensions >=4.5 - - python - constrains: - - trio >=0.32.0 - - uvloop >=0.22.1 - - winloop >=0.2.3 - license: MIT - license_family: MIT - purls: - - pkg:pypi/anyio?source=compressed-mapping - size: 146764 - timestamp: 1774359453364 -- conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf - md5: 54898d0f524c9dee622d44bbb081a8ab - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/appnope?source=hash-mapping - size: 10076 - timestamp: 1733332433806 -- pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl - name: arabic-reshaper - version: 3.0.1 - sha256: 41c5adc2420f85758eada7e880251c4b6a2adbd83377bd27e5d4eba71f648bc7 - requires_dist: - - fonttools>=4.0 ; extra == 'with-fonttools' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad - md5: 8ac12aff0860280ee0cff7fa2cf63f3b - depends: - - argon2-cffi-bindings - - python >=3.9 - - typing-extensions - constrains: - - argon2_cffi ==999 - license: MIT - license_family: MIT - purls: - - pkg:pypi/argon2-cffi?source=hash-mapping - size: 18715 - timestamp: 1749017288144 -- conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda - sha256: b81f852f13a1d148f6ad7e2a29ab375eb1558b73c9bfa38792d98ea7fb414cff - md5: 6e36e9d2b535c3fbe2e093108df26695 - depends: - - __glibc >=2.17,<3.0.a0 - - cffi >=1.0.1 - - libgcc >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 + - __glibc >=2.17,<3.0.a0 + - cffi >=1.0.1 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: @@ -3820,5132 +3635,5549 @@ packages: - pkg:pypi/argon2-cffi-bindings?source=hash-mapping size: 35943 timestamp: 1762509452935 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda - sha256: c15fc1aa6184185f1b31670a16b76d59f484d3efa25b467f28d59088cf0085c0 - md5: 501c2a606787bcd55b9ddee776208333 +- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda + sha256: a23717f9dc06924b988b92ba8dca0f4cb9154cac954457a40adb2f19d57896de + md5: aa8c3009fd8903bebdcb22fbcb4c0dea depends: - - __osx >=11.0 - - cffi >=1.0.1 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 purls: - - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 34403 - timestamp: 1762509963182 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda - sha256: 05ea6fa7109235cfb4fc24526bae1fe82d88bbb5e697ab3945c313f5f041af5b - md5: e23e087109b2096db4cf9a3985bab329 + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 245341 + timestamp: 1777848716685 +- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda + sha256: f92ccaef33713bb66d563e8e829dcdb643e1de8c0d29246a999943c68bb8eb6e + md5: cfe95f3eab50bc3dbd4c3a03f2674bd8 depends: - - __osx >=11.0 - - cffi >=1.0.1 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 purls: - - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 33947 - timestamp: 1762510144907 -- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda - sha256: 787e9a5f0a5624fee2af4f58c823bd7933b8ca560e794dd9a821e990b31d2d49 - md5: 5fde0926a521a37d454a5e3162cb6e51 + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 241034 + timestamp: 1777848719564 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda + sha256: 978ce415ca2868f8415ce54a9c33fe2d2c9efd6a78dc1a6fe79a4bc3d055fe66 + md5: 28b014780cae10a8435d012ef08c0202 depends: - - cffi >=1.0.1 - - python >=3.11,<3.12.0a0 + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT + constrains: + - __glibc >=2.17 + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 38502 - timestamp: 1762509668838 -- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda - sha256: 3f8a1affdfeb2be5289d709e365fc6e386d734773895215cf8cbc5100fa6af9a - md5: eabb4b677b54874d7d6ab775fdaa3d27 + - pkg:pypi/bcrypt?source=hash-mapping + size: 292775 + timestamp: 1762497725251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda + sha256: cdf7496797af275f8bb5edd270aa06303dde623c7dd3a5941b0ce085d8f4cdc5 + md5: b59ec3796cba93d0db5f71e361176f27 depends: - - cffi >=1.0.1 - - python >=3.13,<3.14.0a0 + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT + constrains: + - __glibc >=2.17 + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/argon2-cffi-bindings?source=hash-mapping - size: 38779 - timestamp: 1762509796090 -- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 - md5: 85c4f19f377424eafc4ed7911b291642 + - pkg:pypi/bcrypt?source=hash-mapping + size: 292710 + timestamp: 1762497710166 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda + sha256: c36eb061d9ead85f97644cfb740d485dba9b8823357f35c17851078e95e975c1 + md5: 86daecb8e4ed1042d5dc6efbe0152590 depends: - - python >=3.10 - - python-dateutil >=2.7.0 - - python-tzdata - - python - license: Apache-2.0 - license_family: APACHE + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - libbrotlicommon 1.2.0 hb03c661_1 + license: MIT + license_family: MIT purls: - - pkg:pypi/arrow?source=hash-mapping - size: 113854 - timestamp: 1760831179410 -- pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl - name: asciichartpy - version: 1.5.25 - sha256: 33c417a3c8ef7d0a11b98eb9ea6dd9b2c1b17559e539b207a17d26d4302d0258 - requires_dist: - - setuptools - - flake8 ; extra == 'qa' -- pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl - name: ase - version: 3.28.0 - sha256: 0e24056302d7307b7247f90de281de15e3031c14cf400bedb1116c3b0d0e50b8 - requires_dist: - - numpy>=1.21.6 - - scipy>=1.8.1 - - matplotlib>=3.5.2 - - sphinx ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinxcontrib-video ; extra == 'docs' - - sphinx-gallery ; extra == 'docs' - - pillow ; extra == 'docs' - - pytest>=7.4.0 ; extra == 'test' - - pytest-xdist>=3.2.0 ; extra == 'test' - - spglib>=1.9 ; extra == 'spglib' - - mypy ; extra == 'lint' - - ruff ; extra == 'lint' - - types-docutils ; extra == 'lint' - - types-pymysql ; extra == 'lint' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl - name: asn1crypto - version: 1.5.1 - sha256: db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 -- pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - name: asteval - version: 1.0.8 - sha256: 6c64385c6ff859a474953c124987c7ee8354d781c76509b2c598741c4d1d28e9 - requires_dist: - - build ; extra == 'dev' - - twine ; extra == 'dev' - - sphinx ; extra == 'doc' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - coverage ; extra == 'test' - - asteval[dev,doc,test] ; extra == 'all' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - sha256: ee4da0f3fe9d59439798ee399ef3e482791e48784873d546e706d0935f9ff010 - md5: 9673a61a297b00016442e022d689faa6 + - pkg:pypi/brotli?source=hash-mapping + size: 367573 + timestamp: 1764017405384 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda + sha256: dadec2879492adede0a9af0191203f9b023f788c18efd45ecac676d424c458ae + md5: 6c4d3597cf43f3439a51b2b13e29a4ba depends: - - python >=3.10 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 constrains: - - astroid >=2,<5 - license: Apache-2.0 - license_family: Apache + - libbrotlicommon 1.2.0 hb03c661_1 + license: MIT + license_family: MIT purls: - - pkg:pypi/asttokens?source=hash-mapping - size: 28797 - timestamp: 1763410017955 -- conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - sha256: ea8486637cfb89dc26dc9559921640cd1d5fd37e5e02c33d85c94572139f2efe - md5: b85e84cb64c762569cc1a760c2327e0a + - pkg:pypi/brotli?source=hash-mapping + size: 367721 + timestamp: 1764017371123 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 depends: - - python >=3.10 - - typing_extensions >=4.0.0 - - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 260182 + timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda + sha256: 3ad13377356c86d3a945ae30e9b8c8734300925ef81a3cb0a9db0d755afbe7bb + md5: 3912e4373de46adafd8f1e97e4bd166b + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - pycparser + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - - pkg:pypi/async-lru?source=hash-mapping - size: 22949 - timestamp: 1773926359134 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab - md5: c6b0543676ecb1fb2d7643941fe375f2 + - pkg:pypi/cffi?source=hash-mapping + size: 303338 + timestamp: 1761202960110 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda + sha256: 2162a91819945c826c6ef5efe379e88b1df0fe9a387eeba23ddcf7ebeacd5bd6 + md5: d0616e7935acab407d1543b28c446f6f depends: - - python >=3.10 - - python + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - pycparser + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 license: MIT license_family: MIT purls: - - pkg:pypi/attrs?source=hash-mapping - size: 64927 - timestamp: 1773935801332 -- pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl - name: autopep8 - version: 2.3.2 - sha256: ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128 - requires_dist: - - pycodestyle>=2.12.0 - - tomli ; python_full_version < '3.11' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - sha256: a14a9ad02101aab25570543a59c5193043b73dc311a25650134ed9e6cb691770 - md5: f1976ce927373500cc19d3c0b2c85177 + - pkg:pypi/cffi?source=hash-mapping + size: 298357 + timestamp: 1761202966461 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda + sha256: 838cde68e70f4e0dc6458613316fa0e50eee5cf86cafb1cee4b7ca1a701a8436 + md5: 96f6e551c7ff30c95c1c8b4d2d1c5c9f depends: - - python >=3.10 - - python + - __glibc >=2.17,<3.0.a0 + - cffi >=2.0 + - libgcc >=14 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 constrains: - - pytz >=2015.7 - license: BSD-3-Clause + - __glibc >=2.17 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT license_family: BSD purls: - - pkg:pypi/babel?source=compressed-mapping - size: 7684321 - timestamp: 1772555330347 -- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda - sha256: a23717f9dc06924b988b92ba8dca0f4cb9154cac954457a40adb2f19d57896de - md5: aa8c3009fd8903bebdcb22fbcb4c0dea + - pkg:pypi/cryptography?source=compressed-mapping + size: 1913519 + timestamp: 1777966158377 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda + sha256: 7c10cdde9f46d4b990e9c90ffb72bfb672b56d2ecae243d95582c9a9fc417ebf + md5: 2310978ddde7f742d0b7a642d4894388 depends: - - python - __glibc >=2.17,<3.0.a0 + - cffi >=2.0 - libgcc >=14 - - python_abi 3.11.* *_cp311 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-3-Clause AND MIT AND EPL-2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - __glibc >=2.17 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD purls: - - pkg:pypi/backports-zstd?source=compressed-mapping - size: 245341 - timestamp: 1777848716685 -- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py313h18e8e13_0.conda - sha256: f92ccaef33713bb66d563e8e829dcdb643e1de8c0d29246a999943c68bb8eb6e - md5: cfe95f3eab50bc3dbd4c3a03f2674bd8 + - pkg:pypi/cryptography?source=hash-mapping + size: 1916864 + timestamp: 1777966204947 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda + sha256: e69be2be543c4d4898895d8aebe758bc683c5a1198583ad676f5719782a07131 + md5: 400e4667a12884216df869cad5fb004b depends: - python - libgcc >=14 + - libstdcxx >=14 - __glibc >=2.17,<3.0.a0 - - python_abi 3.13.* *_cp313 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-3-Clause AND MIT AND EPL-2.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT purls: - - pkg:pypi/backports-zstd?source=compressed-mapping - size: 241034 - timestamp: 1777848719564 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda - sha256: 2e6399a3663e7e20134a208cd09befc44ce1e9efe94d1d36d8911db04f186270 - md5: 3ee7e8ae532366221658b80baee36dc0 + - pkg:pypi/debugpy?source=hash-mapping + size: 2733654 + timestamp: 1769744984842 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda + sha256: 8d76d4eeb5a8e3c5666880b465593fdf4a44f47fbbe89ff5b8f9abbe43026326 + md5: e94dbbec2589f3b1d821f43a4bf2ab45 depends: - python - - __osx >=11.0 - - python_abi 3.11.* *_cp311 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-3-Clause AND MIT AND EPL-2.0 + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT purls: - - pkg:pypi/backports-zstd?source=compressed-mapping - size: 244743 - timestamp: 1777848723707 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda - sha256: 257b234caffc760e48c8d7e642d6d0d8bac4341ca19c7df098421358eff636a1 - md5: 84e922fe79295051f6925d7f8d71c98c - depends: - - python - - __osx >=11.0 - - python_abi 3.13.* *_cp313 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=compressed-mapping - size: 242188 - timestamp: 1777848729476 -- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda - sha256: f551f6d7f1a62be18e4165772d300d21e0bd925956bcd9c2a605cabf9a2835d0 - md5: a0b8a2723108680aa6bb85fe3e413e76 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - zstd >=1.5.7,<1.6.0a0 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=hash-mapping - size: 243538 - timestamp: 1777848744191 -- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda - sha256: b9c1465c03cb6ff79fb4f2feb21955b9b89783f868c900cad45dbcb8d81ab429 - md5: ef16917e1231df5c6f2ba245c8fe35e4 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - zstd >=1.5.7,<1.6.0a0 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=compressed-mapping - size: 240632 - timestamp: 1777848740331 -- pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - name: backrefs - version: '7.0' - sha256: f2c52955d631b9e1ac4cd56209f0a3a946d592b98e7790e77699339ae01c102a - requires_dist: - - regex ; extra == 'extras' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl - name: backrefs - version: '7.0' - sha256: a0fa7360c63509e9e077e174ef4e6d3c21c8db94189b9d957289ae6d794b9475 - requires_dist: - - regex ; extra == 'extras' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py311h902ca64_1.conda - sha256: 978ce415ca2868f8415ce54a9c33fe2d2c9efd6a78dc1a6fe79a4bc3d055fe66 - md5: 28b014780cae10a8435d012ef08c0202 + - pkg:pypi/debugpy?source=hash-mapping + size: 2872698 + timestamp: 1769744980407 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a + md5: c80d8a3b84358cb967fa81e7075fbc8a depends: - - python - - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - python_abi 3.11.* *_cp311 - constrains: - - __glibc >=2.17 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 292775 - timestamp: 1762497725251 -- conda: https://conda.anaconda.org/conda-forge/linux-64/bcrypt-5.0.0-py313h843e2db_1.conda - sha256: cdf7496797af275f8bb5edd270aa06303dde623c7dd3a5941b0ce085d8f4cdc5 - md5: b59ec3796cba93d0db5f71e361176f27 - depends: - - python - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.13.* *_cp313 - constrains: - - __glibc >=2.17 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 292710 - timestamp: 1762497710166 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda - sha256: 79594899d1f2472a6d95c3d489268bb9103ba6bab043d9faca379d989074aeb3 - md5: 00ad8eed3ec75b6ec425526968c72e61 - depends: - - python - - python 3.11.* *_cpython - - __osx >=11.0 - - python_abi 3.11.* *_cp311 - constrains: - - __osx >=11.0 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 268519 - timestamp: 1762497846273 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda - sha256: c8e3b95ad2665dc16ac37888fb91dd481fa759bad1fbf799451d12d6bfaec600 - md5: 4b14cba28eaf98170c2ddd7e900efa07 - depends: - - python - - __osx >=11.0 - - python 3.13.* *_cp313 - - python_abi 3.13.* *_cp313 - constrains: - - __osx >=11.0 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 267465 - timestamp: 1762497730829 -- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda - sha256: b4cc5ee88f5d19381923519b1f6a1bbc73752f5b1528e4a1df0a3a802e497d13 - md5: fd25556009eae0faab9fc6286150d477 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 170642 - timestamp: 1762497737769 -- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda - sha256: 21baf1316a8160fd3b83e7128803735b107f47c58ba5d5305a372fd6c679d42b - md5: 2a664b5cc93fbc9d7ca595b206a299f0 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.13.* *_cp313 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/bcrypt?source=hash-mapping - size: 170702 - timestamp: 1762497739995 -- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - sha256: bf1e71c3c0a5b024e44ff928225a0874fc3c3356ec1a0b6fe719108e6d1288f6 - md5: 5267bef8efea4127aacd1f4e1f149b6e - depends: - - python >=3.10 - - soupsieve >=1.2 - - typing-extensions + - libstdcxx >=14 license: MIT license_family: MIT - purls: - - pkg:pypi/beautifulsoup4?source=hash-mapping - size: 90399 - timestamp: 1764520638652 -- pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - name: bidict - version: 0.23.1 - sha256: 5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - sha256: f8ff1f98423674278964a46c93a1766f9e91960d44efd91c6c3ed56a33813f46 - md5: 7c5ebdc286220e8021bf55e6384acd67 - depends: - - python >=3.10 - - webencodings - - python - constrains: - - tinycss2 >=1.1.0,<1.5 - license: Apache-2.0 AND MIT - purls: - - pkg:pypi/bleach?source=hash-mapping - size: 142008 - timestamp: 1770719370680 -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - sha256: 7c07a865e5e4cca233cc4e0eb3f0f5ff6c90776461687b4fb0b1764133e1fd61 - md5: f11a319b9700b203aa14c295858782b6 + purls: [] + size: 12723451 + timestamp: 1773822285671 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 depends: - - bleach ==6.3.0 pyhcf101f3_1 - - tinycss2 - license: Apache-2.0 AND MIT + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later purls: [] - size: 4409 - timestamp: 1770719370682 -- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - name: blinker - version: 1.9.0 - sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda - sha256: c36eb061d9ead85f97644cfb740d485dba9b8823357f35c17851078e95e975c1 - md5: 86daecb8e4ed1042d5dc6efbe0152590 + size: 134088 + timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 + md5: fb53fb07ce46a575c5d004bbc96032c2 depends: - __glibc >=2.17,<3.0.a0 + - keyutils >=1.6.3,<2.0a0 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 - libgcc >=14 - libstdcxx >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - constrains: - - libbrotlicommon 1.2.0 hb03c661_1 + - openssl >=3.5.5,<4.0a0 license: MIT license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 367573 - timestamp: 1764017405384 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda - sha256: dadec2879492adede0a9af0191203f9b023f788c18efd45ecac676d424c458ae - md5: 6c4d3597cf43f3439a51b2b13e29a4ba + purls: [] + size: 1386730 + timestamp: 1769769569681 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c + md5: 18335a698559cdbcd86150a48bf54ba6 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 constrains: - - libbrotlicommon 1.2.0 hb03c661_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 367721 - timestamp: 1764017371123 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda - sha256: 617545ec0e97d35ed2ff7852f2581a20c0dda80b366d0c42a43706687f971ba8 - md5: 150cbf381febcf0a5e470a8d066e1bc0 - depends: - - __osx >=11.0 - - libcxx >=19 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - constrains: - - libbrotlicommon 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 359588 - timestamp: 1764018467340 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda - sha256: 2e21dccccd68bedd483300f9ab87a425645f6776e6e578e10e0dd98c946e1be9 - md5: b03732afa9f4f54634d94eb920dfb308 + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 728002 + timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + sha256: a7a4481a4d217a3eadea0ec489826a69070fcc3153f00443aa491ed21527d239 + md5: 6f7b4302263347698fd24565fbf11310 depends: - - __osx >=11.0 - - libcxx >=19 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 constrains: - - libbrotlicommon 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 359568 - timestamp: 1764018359470 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda - sha256: 1803c838946d79ef6485ae8c7dafc93e28722c5999b059a34118ef758387a4c9 - md5: b0c459f98ac5ea504a9d9df6242f7ee1 + - libabseil-static =20260107.1=cxx17* + - abseil-cpp =20260107.1 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1384817 + timestamp: 1770863194876 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e + md5: 72c8fd1af66bd67bf580645b426513ed depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libbrotlicommon 1.2.0 hfd05255_1 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: MIT license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 335333 - timestamp: 1764018370925 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda - sha256: 3558006cd6e836de8dff53cbe5f0b9959f96ea6a6776b4e14f1c524916dd956c - md5: 916a39a0261621b8c33e9db2366dd427 + purls: [] + size: 79965 + timestamp: 1764017188531 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b + md5: 366b40a69f0ad6072561c1d09301c886 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libbrotlicommon 1.2.0 hfd05255_1 + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 license: MIT license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 335605 - timestamp: 1764018132514 -- pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - name: build - version: 1.5.0 - sha256: 13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f - requires_dist: - - packaging>=24.0 - - pyproject-hooks - - colorama ; os_name == 'nt' - - importlib-metadata>=4.6 ; python_full_version < '3.10.2' - - tomli>=1.1.0 ; python_full_version < '3.11' - - keyring ; extra == 'keyring' - - uv>=0.1.18 ; extra == 'uv' - - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv' - - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl - name: bumps - version: 1.0.4 - sha256: 78b8cfaf9fbcbf2fd77f6d4a2f8c906b0e03a794804ba6caf64d56d6f6cce4d4 - requires_dist: - - numpy - - scipy - - h5py - - dill - - cloudpickle - - matplotlib - - blinker - - aiohttp - - python-socketio - - plotly - - mpld3 - - msgpack - - uncertainties - - build ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - ruff ; extra == 'dev' - - wheel ; extra == 'dev' - - setuptools ; extra == 'dev' - - sphinx ; extra == 'dev' - - versioningit ; extra == 'dev' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 - md5: d2ffd7602c02f2b316fd921d39876885 + purls: [] + size: 34632 + timestamp: 1764017199083 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d + md5: 4ffbb341c8b616aa2494b6afb26a0c5f depends: - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 - libgcc >=14 - license: bzip2-1.0.6 - license_family: BSD + license: MIT + license_family: MIT purls: [] - size: 260182 - timestamp: 1771350215188 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df - md5: 620b85a3f45526a8bc4d23fd78fc22f0 + size: 298378 + timestamp: 1764017210931 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b depends: - - __osx >=11.0 - license: bzip2-1.0.6 + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause license_family: BSD purls: [] - size: 124834 - timestamp: 1771350416561 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 - md5: 4cb8e6b48f67de0b018719cdf1136306 + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: bzip2-1.0.6 + - libgcc-ng >=12 + license: BSD-2-Clause license_family: BSD purls: [] - size: 56115 - timestamp: 1771350256444 -- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e - md5: 920bb03579f15389b9e512095ad995b7 + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda + sha256: ea33c40977ea7a2c3658c522230058395bc2ee0d89d99f0711390b6a1ee80d12 + md5: a3b390520c563d78cc58974de95a03e5 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 + constrains: + - expat 2.8.0.* license: MIT license_family: MIT purls: [] - size: 207882 - timestamp: 1765214722852 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 - md5: bcb3cba70cf1eec964a03b4ba7775f01 + size: 77241 + timestamp: 1777846112704 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 + md5: a360c33a5abe61c07959e449fa1453eb depends: - - __osx >=11.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 180327 - timestamp: 1765215064054 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda - sha256: 6f4ff81534c19e76acf52fcabf4a258088a932b8f1ac56e9a59e98f6051f8e46 - md5: 56fb2c6c73efc627b40c77d14caecfba + size: 58592 + timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 + md5: 0aa00f03f9e39fb9876085dee11a85d4 depends: - - __win - license: ISC + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL purls: [] - size: 131388 - timestamp: 1776865633471 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda - sha256: c9dbcc8039a52023660d6d1bbf87594a93dd69c6ac5a2a44323af2c92976728d - md5: e18ad67cf881dcadee8b8d9e2f8e5f73 + size: 1041788 + timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 + md5: d5e96b1ed75ca01906b3d2469b4ce493 depends: - - __unix - license: ISC + - libgcc 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL purls: [] - size: 131039 - timestamp: 1776865545798 -- conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - noarch: python - sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 - md5: 9b347a7ec10940d3f7941ff6c460b551 + size: 27526 + timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 + md5: 239c5e9546c38a1e884d69effcf4c882 depends: - - cached_property >=1.5.2,<1.5.3.0a0 - license: BSD-3-Clause - license_family: BSD + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL purls: [] - size: 4134 - timestamp: 1615209571450 -- conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - sha256: 6dbf7a5070cc43d90a1e4c2ec0c541c69d8e30a0e25f50ce9f6e4a432e42c5d7 - md5: 576d629e47797577ab0f1b351297ef4a + size: 603262 + timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d + md5: b88d90cad08e6bc8ad540cb310a761fb depends: - - python >=3.6 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cached-property?source=hash-mapping - size: 11065 - timestamp: 1615209567874 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda - sha256: 989db6e5957c4b44fa600c68c681ec2f36a55e48f7c7f1c073d5e91caa8cd878 - md5: 929471569c93acefb30282a22060dcd5 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 113478 + timestamp: 1775825492909 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 + md5: 2c21e66f50753a083cbe6b80f38268fa depends: - - python >=3.10 - license: ISC - purls: - - pkg:pypi/certifi?source=compressed-mapping - size: 135656 - timestamp: 1776866680878 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda - sha256: 3ad13377356c86d3a945ae30e9b8c8734300925ef81a3cb0a9db0d755afbe7bb - md5: 3912e4373de46adafd8f1e97e4bd166b + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 92400 + timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f + md5: 2a45e7f8af083626f009645a6481f12d depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.5.2,<3.6.0a0 + - c-ares >=1.34.6,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 - libgcc >=14 - - pycparser - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 license: MIT license_family: MIT - purls: - - pkg:pypi/cffi?source=hash-mapping - size: 303338 - timestamp: 1761202960110 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda - sha256: 2162a91819945c826c6ef5efe379e88b1df0fe9a387eeba23ddcf7ebeacd5bd6 - md5: d0616e7935acab407d1543b28c446f6f + purls: [] + size: 663344 + timestamp: 1773854035739 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 + md5: d864d34357c3b65a4b731f78c0801dc4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-only + license_family: GPL + purls: [] + size: 33731 + timestamp: 1750274110928 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda + sha256: 64e5c80cbce4680a2d25179949739a6def695d72c40ca28f010711764e372d97 + md5: 7af961ef4aa2c1136e11dd43ded245ab + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: ISC + purls: [] + size: 277661 + timestamp: 1772479381288 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d + md5: 7dc38adcbf71e6b38748e919e16e0dce + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 954962 + timestamp: 1777986471789 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e + md5: 1b08cd684f34175e4514474793d44bcb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_18 + constrains: + - libstdcxx-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 5852330 + timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda + sha256: bc1b08c92626c91500fd9f26f2c797f3eb153b627d53e9c13cd167f1e12b2829 + md5: 38ffe67b78c9d4de527be8315e5ada2c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 40297 + timestamp: 1775052476770 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - pycparser - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 license: MIT license_family: MIT - purls: - - pkg:pypi/cffi?source=hash-mapping - size: 298357 - timestamp: 1761202966461 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda - sha256: 1ffde698463d6e7ed571bdb85cb17bfc1d3a107c026d20047995512dcc2749ec - md5: 4d7f6780e36f18e7601811dddf3bbec5 + purls: [] + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - pycparser + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 + md5: d87ff7921124eccd67248aa483c23fec + depends: + - __glibc >=2.17,<3.0.a0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 63629 + timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda + sha256: 710e207b2e91308a34bcfe547c60ad86c1fa294827266ba18548c1fe1a9d8333 + md5: f9efdf9b0f3d0cc309d56af6edf2a6b0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/cffi?source=hash-mapping - size: 294848 - timestamp: 1761203196617 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda - sha256: 1fa69651f5e81c25d48ac42064db825ed1a3e53039629db69f86b952f5ce603c - md5: 050374657d1c7a4f2ea443c0d0cbd9a0 + - pkg:pypi/markupsafe?source=hash-mapping + size: 26756 + timestamp: 1772445078834 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda + sha256: 72ed7c0216541d65a17b171bf2eec4a3b81e9158d8ed48e59e1ecd3ae302d263 + md5: aeb9b9da79fd0258b3db091d1fefcd71 depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - pycparser + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/cffi?source=hash-mapping - size: 291376 - timestamp: 1761203583358 -- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda - sha256: c9caca6098e3d92b1a269159b759d757518f2c477fbbb5949cb9fee28807c1f1 - md5: f02335db0282d5077df5bc84684f7ff9 + - pkg:pypi/markupsafe?source=hash-mapping + size: 26100 + timestamp: 1772445154165 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda + sha256: 59123ba4af69c1e7ca6b1b8ffcc40f2aff9a635814495bda3f4f555b3b929165 + md5: 0347d2804701019ac005528df9eb502c depends: - - pycparser + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/cffi?source=hash-mapping - size: 297941 - timestamp: 1761203850323 -- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda - sha256: f867a11f42bb64a09b232e3decf10f8a8fe5194d7e3a216c6bac9f40483bd1c6 - md5: 55b44664f66a2caf584d72196aa98af9 + - pkg:pypi/msgspec?source=hash-mapping + size: 217556 + timestamp: 1776337480302 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda + sha256: a44d23085117672e4e19629ea3e6c53f516984322513c4bfdd052b1c7c6fc8ad + md5: 15c679f7133347d68058b688f3519cea depends: - - pycparser + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/cffi?source=hash-mapping - size: 292681 - timestamp: 1761203203673 -- pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - name: cfgv - version: 3.5.0 - sha256: a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/14/4b/d3c79495dee4831b8bebca2790e72cb90f0c5849c940570a7c7e5b70b952/chardet-7.4.3-cp311-cp311-macosx_11_0_arm64.whl - name: chardet - version: 7.4.3 - sha256: 7005c88da26fd95d8abb8acbe6281d833e9a9181b03cf49b4546c4555389bd97 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl - name: chardet - version: 7.4.3 - sha256: e1b98790c284ff813f18f7cf7de5f05ea2435a080030c7f1a8318f3a4f80b131 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl - name: chardet - version: 7.4.3 - sha256: 4fbff1907925b0c5a1064cffb5e040cd5e338585c9c552625f30de6bc2f3107a - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl - name: chardet - version: 7.4.3 - sha256: ccc1f83ab4bcfb901cf39e0c4ba6bc6e726fc6264735f10e24ceb5cb47387578 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: chardet - version: 7.4.3 - sha256: bfc134b70c846c21ead8e43ada3ae1a805fff732f6922f8abcf2ff27b8f6493d - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: chardet - version: 7.4.3 - sha256: 4c3da294de1a681097848ab58bd3f2771a674f8039d2d87a5538b28856b815e9 - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 - md5: a9167b9571f3baa9d448faa2139d1089 + - pkg:pypi/msgspec?source=hash-mapping + size: 219767 + timestamp: 1776337423071 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 + md5: fc21868a1a5aacc937e7a18747acb8a5 depends: - - python >=3.10 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: X11 AND BSD-3-Clause + purls: [] + size: 918956 + timestamp: 1777422145199 +- conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda + sha256: d1a673d1418d9e956b6e4e46c23e72a511c5c1d45dc5519c947457427036d5e2 + md5: baffb1570b3918c784d4490babc52fbf + depends: + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.28,<3.0.a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libuv >=1.51.0,<2.0a0 + - c-ares >=1.34.6,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - libsqlite >=3.52.0,<4.0a0 + - icu >=78.3,<79.0a0 + - libzlib >=1.3.2,<2.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + - zstd >=1.5.7,<1.6.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 license: MIT license_family: MIT - purls: - - pkg:pypi/charset-normalizer?source=compressed-mapping - size: 58872 - timestamp: 1775127203018 -- pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl - name: click - version: 8.3.3 - sha256: a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 - requires_dist: - - colorama ; sys_platform == 'win32' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - name: cloudpickle - version: 3.1.2 - sha256: 9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 - md5: 962b9857ee8e7018c22f2776ffa0b2d7 + purls: [] + size: 18829340 + timestamp: 1774514313036 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb + md5: da1b85b6a87e141f5140bb9924cecab0 depends: - - python >=3.9 + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3167099 + timestamp: 1775587756857 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda + sha256: 8d9325af538a8f56013e42bbb91a4dc6935aece34476e20bafacf6007b571e86 + md5: 2ed8f6fe8b51d8e19f7621941f7bb95f + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.11.* *_cp311 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/colorama?source=hash-mapping - size: 27011 - timestamp: 1733218222191 -- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 - md5: 2da13f2b299d8e1995bafbbe9689a2f7 + - pkg:pypi/psutil?source=hash-mapping + size: 231786 + timestamp: 1769678156460 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda + sha256: f19fd682d874689dfde20bf46d7ec1a28084af34583e0405685981363af47c91 + md5: 25fe6e02c2083497b3239e21b49d8093 depends: - - python >=3.9 - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.13.* *_cp313 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/comm?source=hash-mapping - size: 14690 - timestamp: 1753453984907 -- pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl - name: contourpy - version: 1.3.3 - sha256: 23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - name: contourpy - version: 1.3.3 - sha256: 1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: contourpy - version: 1.3.3 - sha256: 4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: contourpy - version: 1.3.3 - sha256: 51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - name: contourpy - version: 1.3.3 - sha256: d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl - name: contourpy - version: 1.3.3 - sha256: 3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 - requires_dist: - - numpy>=1.25 - - furo ; extra == 'docs' - - sphinx>=7.2 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - bokeh ; extra == 'bokeh' - - selenium ; extra == 'bokeh' - - contourpy[bokeh,docs] ; extra == 'mypy' - - bokeh ; extra == 'mypy' - - docutils-stubs ; extra == 'mypy' - - mypy==1.17.0 ; extra == 'mypy' - - types-pillow ; extra == 'mypy' - - contourpy[test-no-images] ; extra == 'test' - - matplotlib ; extra == 'test' - - pillow ; extra == 'test' - - pytest ; extra == 'test-no-images' - - pytest-cov ; extra == 'test-no-images' - - pytest-rerunfailures ; extra == 'test-no-images' - - pytest-xdist ; extra == 'test-no-images' - - wurlitzer ; extra == 'test-no-images' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda - sha256: 2ceb1f7edb5e5943f7af69e4d6b3339b2e2580e7c9eef76efed4d18d05ae49db - md5: 12baf87bfa62ac066dbe2526f5d89de1 + - pkg:pypi/psutil?source=hash-mapping + size: 228663 + timestamp: 1769678153829 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda + sha256: ac3faa31154a85f4b1a4618957b4a06623ff2c6a85f8eac20efe9dbac5757d91 + md5: b6cfa054aec29586d383f9e666bd0e9a depends: - - python >=3.10 - - colorama >=0.4.6 - - dunamai >=1.7.0 - - funcy >=1.17 - - jinja2 >=3.1.5 - - jinja2-ansible-filters >=1.3.1 - - packaging >=23.0 - - pathspec >=0.9.0 - - plumbum >=1.6.9 - - prompt-toolkit <3.0.52 - - pydantic >=2.4.2 - - pygments >=2.7.1 - - pyyaml >=5.3.1 - - questionary >=1.8.1 - - eval-type-backport >=0.1.3,<0.3.0 - - platformdirs >=4.3.6 - - typing_extensions >=4.0.0,<5.0.0 - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/copier?source=hash-mapping - size: 58609 - timestamp: 1777562504238 -- pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl - name: coverage - version: 7.13.5 - sha256: 941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3 - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl - name: coverage - version: 7.13.5 - sha256: 145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587 - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl - name: coverage - version: 7.13.5 - sha256: 631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: coverage - version: 7.13.5 - sha256: ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: coverage - version: 7.13.5 - sha256: 78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl - name: coverage - version: 7.13.5 - sha256: 258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9 - requires_dist: - - tomli ; python_full_version <= '3.11' and extra == 'toml' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda - noarch: generic - sha256: 836b92c209d4b6b9fb28bd51bd788b22a0c5492ae95eec2724e65a15ed4ab2e1 - md5: 3a8a8b87e72f95b54689fb588e154ec9 - depends: - - python >=3.13,<3.14.0a0 - - python_abi * *_cp313 - license: Python-2.0 - purls: [] - size: 48530 - timestamp: 1775613723457 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py311h2005dd1_0.conda - sha256: 838cde68e70f4e0dc6458613316fa0e50eee5cf86cafb1cee4b7ca1a701a8436 - md5: 96f6e551c7ff30c95c1c8b4d2d1c5c9f - depends: + - typing-extensions >=4.6.0,!=4.7.0 - __glibc >=2.17,<3.0.a0 - - cffi >=2.0 - libgcc >=14 - - openssl >=3.5.6,<4.0a0 - - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 constrains: - __glibc >=2.17 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD + license: MIT + license_family: MIT purls: - - pkg:pypi/cryptography?source=compressed-mapping - size: 1913519 - timestamp: 1777966158377 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-48.0.0-py313heb322e3_0.conda - sha256: 7c10cdde9f46d4b990e9c90ffb72bfb672b56d2ecae243d95582c9a9fc417ebf - md5: 2310978ddde7f742d0b7a642d4894388 + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1884122 + timestamp: 1778084220486 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda + sha256: d6705962afa2655cc22edcd075ce1f7e67c4407c005137d6d63c0dc5eaa76f47 + md5: ef0f9efec6ec28b17e22f787c7672c67 depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 - __glibc >=2.17,<3.0.a0 - - cffi >=2.0 - libgcc >=14 - - openssl >=3.5.6,<4.0a0 - - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 constrains: - __glibc >=2.17 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD + license: MIT + license_family: MIT purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1916864 - timestamp: 1777966204947 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda - sha256: 6e59412439c8b51ee5f05b3c50b05b43991fa544a895226168fab63be9ba28f9 - md5: cbc7fb4eb2049a4a6cd2c452afd2f7bd + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1893749 + timestamp: 1778084222642 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda + sha256: 4b89f502dc58df0abb27d4677ca4b0ef5230f5c28e24b80eef3dc0c9c968e225 + md5: fb7e00fed4fddee97e6cf0bd3ae9a27e depends: - - __osx >=11.0 - - cffi >=2.0 - - openssl >=3.5.6,<4.0a0 + - __glibc >=2.17,<3.0.a0 + - cffi >=1.4.1 + - libgcc >=14 + - libsodium >=1.0.21,<1.0.22.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - constrains: - - __osx >=11.0 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD + - six + license: Apache-2.0 + license_family: Apache purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1855763 - timestamp: 1777966249758 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda - sha256: 2adca86f420558eaaad8b8a7ecffadc4a23f980c02716d0fd5bee3f51879e76b - md5: 730fd8d2542ece52b71bc4fbb80ceb10 + - pkg:pypi/pynacl?source=hash-mapping + size: 1151915 + timestamp: 1772171237221 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda + sha256: 51e80a7bef95025ad47a92acb69ee0e78f01e107655c86fe76abcde2ac688166 + md5: c4426edfc5514a2c9be6871557bce52b depends: - - __osx >=11.0 - - cffi >=2.0 - - openssl >=3.5.6,<4.0a0 + - __glibc >=2.17,<3.0.a0 + - cffi >=1.4.1 + - libgcc >=14 + - libsodium >=1.0.21,<1.0.22.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - constrains: - - __osx >=11.0 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD + - six + license: Apache-2.0 + license_family: Apache purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1854514 - timestamp: 1777966313532 -- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda - sha256: a6fca5c54f019724d08fc3d9e54c60ca8c0c8aa8b54571fec3e713bbb64a55c3 - md5: 27def055167d830e4ce6c6821eaee591 + - pkg:pypi/pynacl?source=hash-mapping + size: 1191901 + timestamp: 1772171244923 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda + sha256: bf6a32c69889d38482436a786bea32276756cedf0e9805cc856ffd088e8d00f0 + md5: a5ebcefec0c12a333bcd6d7bf3bddc1f depends: - - cffi >=2.0 - - openssl >=3.5.6,<4.0a0 - - python >=3.11,<3.12.0a0 + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libnsl >=2.0.1,<2.1.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libxcrypt >=4.4.36 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD - purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1645132 - timestamp: 1777966325193 -- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda - sha256: 1fbf66094059379d72f06d3cbb9df5277352a95d25a68d55d1dd60fa6acca5c6 - md5: c216777102e0b49ed307e181df3903d2 + license: Python-2.0 + purls: [] + size: 30949404 + timestamp: 1772730362552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda + build_number: 100 + sha256: 7f77eb57648f545c1f58e10035d0d9d66b0a0efb7c4b58d3ed89ec7269afdde1 + md5: 05051be49267378d2fcd12931e319ac3 depends: - - cffi >=2.0 - - openssl >=3.5.6,<4.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT - license_family: BSD - purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1646298 - timestamp: 1777966340031 -- pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl - name: crysfml - version: 0.6.2 - sha256: 0010858646240f6c64e2711c33ccfffd94ee6602859babd1186785e28d6c5c11 - requires_dist: - - numpy - requires_python: '>=3.11,<3.15' -- pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: crysfml - version: 0.6.2 - sha256: 734e2180b2c427e77cc9cf9cee4a3651ad563adab28dfe79051f004489f8546c - requires_dist: - - numpy - requires_python: '>=3.11,<3.15' -- pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl - name: crysfml - version: 0.6.2 - sha256: b32ddbf4010ce61a535182d58c12c410ed4a0f5de2259e7ef605e7fbcce40be3 - requires_dist: - - numpy - requires_python: '>=3.11,<3.15' -- pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl - name: cryspy - version: 0.11.0 - sha256: 0b650655a0fbdc3cfcb28826c2ab9fbc5f491e32e1ea9a47d9b75976cd43f26f - requires_dist: - - numpy - - scipy - - pycifstar - - matplotlib -- pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl - name: cssselect2 - version: 0.9.0 - sha256: 6a99e5f91f9a016a304dd929b0966ca464bcfda15177b6fb4a118fc0fb5d9563 - requires_dist: - - tinycss2 - - webencodings - - sphinx ; extra == 'doc' - - furo ; extra == 'doc' - - pytest ; extra == 'test' - - ruff ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl - name: cyclebane - version: 24.10.0 - sha256: 902dd318667e4a222afc270cc5bc72c67d5d6047d2e0e1c36018885fb80f5e5d - requires_dist: - - networkx - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - name: cycler - version: 0.12.1 - sha256: 85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 - requires_dist: - - ipython ; extra == 'docs' - - matplotlib ; extra == 'docs' - - numpydoc ; extra == 'docs' - - sphinx ; extra == 'docs' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl - name: darkdetect - version: 0.8.0 - sha256: a7509ccf517eaad92b31c214f593dbcf138ea8a43b2935406bbd565e15527a85 - requires_dist: - - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'macos-listener' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl - name: dask - version: 2026.3.0 - sha256: be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d - requires_dist: - - click>=8.1 - - cloudpickle>=3.0.0 - - fsspec>=2021.9.0 - - packaging>=20.0 - - partd>=1.4.0 - - pyyaml>=5.3.1 - - toolz>=0.12.0 - - importlib-metadata>=4.13.0 ; python_full_version < '3.12' - - numpy>=1.24 ; extra == 'array' - - dask[array] ; extra == 'dataframe' - - pandas>=2.0 ; extra == 'dataframe' - - pyarrow>=16.0 ; extra == 'dataframe' - - distributed>=2026.3.0,<2026.3.1 ; extra == 'distributed' - - bokeh>=3.1.0 ; extra == 'diagnostics' - - jinja2>=2.10.3 ; extra == 'diagnostics' - - dask[array,dataframe,diagnostics,distributed] ; extra == 'complete' - - pyarrow>=16.0 ; extra == 'complete' - - lz4>=4.3.2 ; extra == 'complete' - - pandas[test] ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - pre-commit ; extra == 'test' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py311hc665b79_0.conda - sha256: e69be2be543c4d4898895d8aebe758bc683c5a1198583ad676f5719782a07131 - md5: 400e4667a12884216df869cad5fb004b - depends: - - python + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - libstdcxx >=14 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libuuid >=2.42,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + license: Python-2.0 + purls: [] + size: 37358322 + timestamp: 1775614712638 + python_site_packages_path: lib/python3.13/site-packages +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda + sha256: c9a6cd2c290d7c3d2b30ea34a0ccda30f770e8ddb2937871f2c404faf60d0050 + md5: a24add9a3bababee946f3bc1c829acfe + depends: - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 + - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2733654 - timestamp: 1769744984842 -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py313h5d5ffb9_0.conda - sha256: 8d76d4eeb5a8e3c5666880b465593fdf4a44f47fbbe89ff5b8f9abbe43026326 - md5: e94dbbec2589f3b1d821f43a4bf2ab45 + - pkg:pypi/pyyaml?source=hash-mapping + size: 206190 + timestamp: 1770223702917 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda + sha256: ef7df29b38ef04ec67a8888a4aa039973eaa377e8c4b59a7be0a1c50cd7e4ac6 + md5: f256753e840c3cd3766488c9437a8f8b depends: - - python - - libstdcxx >=14 - - libgcc >=14 - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 + - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2872698 - timestamp: 1769744980407 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda - sha256: 093b015e9abf27fb4d3b4f7e52417d35cd69a99fab8b95ec5c6c3983275c46ba - md5: 150c921424bc9f08c0378f8a6ae58d05 + - pkg:pypi/pyyaml?source=compressed-mapping + size: 201616 + timestamp: 1770223543730 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda + sha256: 4137226663b353919396f8cf239971cfa54107cd077cf3b65e979ba3e1f8a037 + md5: 759edfe34f07c5c4565b6c5ec0c7fb17 depends: - python - - __osx >=11.0 - - libcxx >=19 - - python 3.11.* *_cpython + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - zeromq >=4.3.5,<4.4.0a0 - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2668163 - timestamp: 1769745020016 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda - sha256: 372464b345220758769f49e76d125933008abec7048df4077a851adcc79da1e8 - md5: b3a832c19cfa5dfcce7575750ef693ed + - pkg:pypi/pyzmq?source=hash-mapping + size: 383627 + timestamp: 1771716979818 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda + noarch: python + sha256: be66c1f85c3b48137200d62c12d918f4f8ad329423daef04fed292818efd3c28 + md5: 082985717303dab433c976986c674b35 depends: - python - - libcxx >=19 - - python 3.13.* *_cp313 - - __osx >=11.0 - - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - zeromq >=4.3.5,<4.4.0a0 + - _python_abi3_support 1.* + - cpython >=3.12 + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2761021 - timestamp: 1769744996428 -- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda - sha256: 661e5c582b1f853a46a78d4bb6e55f2bfdac66e68d015e111f1580a11c28abbf - md5: 683be2cd10e80a367790b3083ce529b7 + - pkg:pypi/pyzmq?source=hash-mapping + size: 211567 + timestamp: 1771716961404 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda + sha256: bf5e6197fb08b8c6e421ca0126e966b7c3ae62b84d7b98523356b4fd5ae6f8ae + md5: 3893f7b40738f9fe87510cb4468cdda5 depends: - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python_abi 3.11.* *_cp311 + constrains: + - __glibc >=2.17 license: MIT license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 3940002 - timestamp: 1769745017274 -- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda - sha256: f6fe9cbd9e3d3c09f173eeb43676a58bc6169e97da0d190e0201e40828a3a62b - md5: 75eb3091b05924429a3a8d2a9bbdfac2 + - pkg:pypi/rpds-py?source=hash-mapping + size: 383153 + timestamp: 1764543197251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda + sha256: 076d26e51c62c8ecfca6eb19e3c1febdd7632df1990a7aa53da5df5e54482b1c + md5: 779e3307a0299518713765b83a36f4b1 depends: - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 - python_abi 3.13.* *_cp313 - license: MIT + constrains: + - __glibc >=2.17 + license: MIT license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 4003589 - timestamp: 1769745018248 -- conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 - md5: 9ce473d1d1be1cc3810856a48b3fab32 + - pkg:pypi/rpds-py?source=hash-mapping + size: 383230 + timestamp: 1764543223529 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda + noarch: python + sha256: 98c771464ed93a2733bae460c39cfa9640feb20972d2e651b44e85db296942eb + md5: 3c8f229055ad244fa3a97c6c45b77099 depends: - - python >=3.9 - license: BSD-2-Clause + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 9266480 + timestamp: 1778119386343 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + constrains: + - xorg-libx11 >=1.8.12,<2.0a0 + license: TCL license_family: BSD + purls: [] + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda + sha256: cd8bc08ca661291cfbb05581b79f7e6a6971a072a54a335abcea5460c1230880 + md5: 73b44a114241e564deb5846e7394bf19 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: Apache purls: - - pkg:pypi/decorator?source=hash-mapping - size: 14129 - timestamp: 1740385067843 -- conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be - md5: 961b3a227b437d82ad7054484cfa71b2 + - pkg:pypi/tornado?source=compressed-mapping + size: 876817 + timestamp: 1774358035290 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda + sha256: 9e8497e1ecca77d03c6be2d3b5f901dfe0ab99686af4fb94ab418b7d449ac547 + md5: 6c0b0ae017b5bfd9c8d718217efd8f14 depends: - - python >=3.6 - license: PSF-2.0 - license_family: PSF + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache purls: - - pkg:pypi/defusedxml?source=hash-mapping - size: 24062 - timestamp: 1615232388757 -- pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl - name: dfo-ls - version: 1.6.5 - sha256: d147d42e471e240f9abf8bc38351a88f555ea6a8fcfd83119bbbf93c36f75ab2 - requires_dist: - - setuptools - - numpy - - scipy>=1.11 - - pandas - - pytest ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-rtd-theme ; extra == 'dev' - - trustregion>=1.1 ; extra == 'trustregion' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl - name: diffpy-pdffit2 - version: 1.6.0 - sha256: f1bba407eac8ff8ef1264ad5a1d3dff840e2d0a5f71e9fb0c0b9b06d5a8eb139 - requires_dist: - - diffpy-structure - requires_python: '>=3.12,<3.15' -- pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz - name: diffpy-pdffit2 - version: 1.6.0 - sha256: 11a65466f8790f5ac7ae45f2f3fc0d5d116d156d274bcfc079df653123d080e2 - requires_dist: - - diffpy-structure - requires_python: '>=3.12,<3.15' -- pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl - name: diffpy-pdffit2 - version: 1.6.0 - sha256: 8837088196ddabd688deb77740c3f03ddc33f0df6964a8e3507701c32b67b8b2 - requires_dist: - - diffpy-structure - requires_python: '>=3.12,<3.15' -- pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl - name: diffpy-structure - version: 3.4.0 - sha256: bd0f06a96635d80316f51ebc0a08003bdeb2cb48c9bb18cbed1455ac60645e48 - requires_dist: - - numpy - - pycifrw - - diffpy-utils - requires_python: '>=3.12,<3.15' -- pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl - name: diffpy-utils - version: 3.7.2 - sha256: 6100600736791a8e4638e3dd476704f4dabe3cab75bcb5c60c83c16a2032519a - requires_dist: - - numpy - - xraydb - - scipy - requires_python: '>=3.10,<3.15' -- pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - name: dill - version: 0.4.1 - sha256: 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d - requires_dist: - - objgraph>=1.7.2 ; extra == 'graph' - - gprof2dot>=2022.7.29 ; extra == 'profile' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - name: distlib - version: 0.4.0 - sha256: 9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 -- pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl - name: dnspython - version: 2.8.0 - sha256: 01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af - requires_dist: - - black>=25.1.0 ; extra == 'dev' - - coverage>=7.0 ; extra == 'dev' - - flake8>=7 ; extra == 'dev' - - hypercorn>=0.17.0 ; extra == 'dev' - - mypy>=1.17 ; extra == 'dev' - - pylint>=3 ; extra == 'dev' - - pytest-cov>=6.2.0 ; extra == 'dev' - - pytest>=8.4 ; extra == 'dev' - - quart-trio>=0.12.0 ; extra == 'dev' - - sphinx-rtd-theme>=3.0.0 ; extra == 'dev' - - sphinx>=8.2.0 ; extra == 'dev' - - twine>=6.1.0 ; extra == 'dev' - - wheel>=0.45.0 ; extra == 'dev' - - cryptography>=45 ; extra == 'dnssec' - - h2>=4.2.0 ; extra == 'doh' - - httpcore>=1.0.0 ; extra == 'doh' - - httpx>=0.28.0 ; extra == 'doh' - - aioquic>=1.2.0 ; extra == 'doq' - - idna>=3.10 ; extra == 'idna' - - trio>=0.30 ; extra == 'trio' - - wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl - name: docstring-parser-fork - version: 0.0.14 - sha256: 4c544f234ef2cc2749a3df32b70c437d77888b1099143a1ad5454452c574b9af - requires_dist: - - docstring-parser[docs] ; extra == 'dev' - - docstring-parser[test] ; extra == 'dev' - - pre-commit>=2.16.0 ; python_full_version >= '3.9' and extra == 'dev' - - pydoctor>=25.4.0 ; extra == 'docs' - - pytest ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl - name: docstripy - version: 0.7.2 - sha256: c4ba35de6c1b1c51f7afad4a46d8953aad55dce1a490d198f7e98c8c63efefda - requires_dist: - - nbformat - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda - sha256: 930f21584babebdabc8310f894557d032211f6cb427f7028c7c92cab6fe6cc1f - md5: dbb824a3a87ac1e2ce02f8227be67e74 + - pkg:pypi/tornado?source=hash-mapping + size: 882996 + timestamp: 1774358035145 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad + md5: a77f85f77be52ff59391544bfe73390a depends: - - importlib-metadata >=1.6.0 - - packaging >=20.9 - - python >=3.10 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + purls: [] + size: 85189 + timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda + sha256: 325d370b28e2b9cc1f765c5b4cdb394c91a5d958fbd15da1a14607a28fee09f6 + md5: 755b096086851e1193f3b10347415d7c + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - krb5 >=1.22.2,<1.23.0a0 + - libsodium >=1.0.21,<1.0.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 311150 + timestamp: 1772476812121 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 + md5: aaa2a381ccc56eac91d63b6c1240312f + depends: + - cpython + - python-gil + license: MIT + license_family: MIT + purls: [] + size: 8191 + timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda + sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 + md5: 2934f256a8acfe48f6ebb4fce6cde29c + depends: + - python >=3.9 + - typing-extensions >=4.0.0 license: MIT license_family: MIT purls: - - pkg:pypi/dunamai?source=hash-mapping - size: 30866 - timestamp: 1775597880526 -- pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl - name: easydiffraction - version: 0.16.0 - sha256: 2691a1e175974ca79e0ec3c219d92b77f277c38fb3b0b8d25f6f7e99696bf70f - requires_dist: - - asciichartpy - - asteval - - bumps - - colorama - - crysfml - - cryspy - - darkdetect - - dfo-ls - - diffpy-pdffit2 - - diffpy-utils - - essdiffraction - - gemmi - - lmfit - - numpy - - pandas - - plotly - - pooch - - py3dmol - - rich - - scipy - - sympy - - tabulate - - typeguard - - typer - - uncertainties - - varname - - build ; extra == 'dev' - - copier ; extra == 'dev' - - docstripy ; extra == 'dev' - - format-docstring ; extra == 'dev' - - gitpython ; extra == 'dev' - - interrogate ; extra == 'dev' - - jinja2 ; extra == 'dev' - - jupyterquiz ; extra == 'dev' - - jupytext ; extra == 'dev' - - mike ; extra == 'dev' - - mkdocs ; extra == 'dev' - - mkdocs-autorefs ; extra == 'dev' - - mkdocs-jupyter ; extra == 'dev' - - mkdocs-markdownextradata-plugin ; extra == 'dev' - - mkdocs-material ; extra == 'dev' - - mkdocs-plugin-inline-svg ; extra == 'dev' - - mkdocstrings-python ; extra == 'dev' - - nbmake ; extra == 'dev' - - nbqa ; extra == 'dev' - - nbstripout ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydoclint ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-benchmark ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pyyaml ; extra == 'dev' - - radon ; extra == 'dev' - - ruff ; extra == 'dev' - - spdx-headers ; extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - versioningit ; extra == 'dev' - requires_python: '>=3.12' -- pypi: ./ - name: easyreflectometry - version: 1.5.0+devdirty9 - sha256: 6cb81566f4ddb1401f1f6cfdac62844e904c9e177f74d0526912a44ae0489a16 - requires_dist: - - bumps - - easyscience - - orsopy - - pooch - - refl1d>=1.0.0 - - refnx - - scipp - - svglib<1.6 ; sys_platform == 'darwin' or sys_platform == 'linux' - - xhtml2pdf - - build ; extra == 'dev' - - copier ; extra == 'dev' - - docstripy ; extra == 'dev' - - format-docstring ; extra == 'dev' - - gitpython ; extra == 'dev' - - interrogate ; extra == 'dev' - - jinja2 ; extra == 'dev' - - jupyterquiz ; extra == 'dev' - - jupytext ; extra == 'dev' - - mike ; extra == 'dev' - - mkdocs ; extra == 'dev' - - mkdocs-autorefs ; extra == 'dev' - - mkdocs-jupyter ; extra == 'dev' - - mkdocs-markdownextradata-plugin ; extra == 'dev' - - mkdocs-material ; extra == 'dev' - - mkdocs-plugin-inline-svg ; extra == 'dev' - - mkdocstrings-python ; extra == 'dev' - - nbmake ; extra == 'dev' - - nbqa ; extra == 'dev' - - nbstripout ; extra == 'dev' - - plopp ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydoclint ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pyyaml ; extra == 'dev' - - radon ; extra == 'dev' - - ruff ; extra == 'dev' - - spdx-headers ; extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - versioningit ; extra == 'dev' - requires_python: '>=3.11' - editable: true -- pypi: https://files.pythonhosted.org/packages/4a/8a/4cb9367a86f2b9526727ee94e5e6a3d86f9f7d7d947927b444e5bcd56a89/easyscience-2.3.1-py3-none-any.whl - name: easyscience - version: 2.3.1 - sha256: 51dd343ff4bcf7c36e8fada32ed3ca2bdc7e1226ae08965a2c11d9fd936e3e40 - requires_dist: - - asteval - - bumps - - dfo-ls - - ipykernel - - ipympl - - ipython - - ipywidgets - - jupyterlab - - lmfit - - matplotlib - - numpy - - pixi-kernel - - pooch - - scipp - - uncertainties - - build ; extra == 'dev' - - copier ; extra == 'dev' - - docformatter ; extra == 'dev' - - gitpython ; extra == 'dev' - - interrogate ; extra == 'dev' - - jinja2 ; extra == 'dev' - - jupyterquiz ; extra == 'dev' - - jupytext ; extra == 'dev' - - mike ; extra == 'dev' - - mkdocs ; extra == 'dev' - - mkdocs-autorefs ; extra == 'dev' - - mkdocs-jupyter ; extra == 'dev' - - mkdocs-markdownextradata-plugin ; extra == 'dev' - - mkdocs-material ; extra == 'dev' - - mkdocs-plugin-inline-svg ; extra == 'dev' - - mkdocstrings-python ; extra == 'dev' - - nbmake ; extra == 'dev' - - nbqa ; extra == 'dev' - - nbstripout ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pyyaml ; extra == 'dev' - - radon ; extra == 'dev' - - ruff ; extra == 'dev' - - spdx-headers ; extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - versioningit ; extra == 'dev' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - name: email-validator - version: 2.3.0 - sha256: 80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4 - requires_dist: - - dnspython>=2.0.0 - - idna>=2.0.0 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl - name: essdiffraction - version: 26.5.1 - sha256: 8a6c779078c71be250714619214069221ab7968a69580d4e4d3f4b3e9a1a53ad - requires_dist: - - dask>=2022.1.0 - - essreduce>=26.4.0 - - graphviz - - numpy>=2 - - plopp>=26.2.0 - - pythreejs>=2.4.1 - - sciline>=25.4.1 - - scipp>=25.11.0 - - scippneutron>=26.3.0 - - scippnexus>=23.12.0 - - tof>=25.12.0 - - ncrystal[cif]>=4.1.0 - - spglib!=2.7 - - pandas>=2.1.2 ; extra == 'test' - - pooch>=1.5 ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - ipywidgets>=8.1.7 ; extra == 'test' - - autodoc-pydantic ; extra == 'docs' - - ipykernel ; extra == 'docs' - - ipympl ; extra == 'docs' - - ipython!=8.7.0 ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbsphinx ; extra == 'docs' - - pandas ; extra == 'docs' - - pooch ; extra == 'docs' - - pydata-sphinx-theme>=0.14 ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-design ; extra == 'docs' - - sphinxcontrib-bibtex ; extra == 'docs' - - pyarrow ; extra == 'docs' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl - name: essreduce - version: 26.4.1 - sha256: 1758a18fffca9c7c2a6fa9547cf87bf45f9d52fc3ccbdffcf7524f71bc060424 - requires_dist: - - sciline>=25.11.0 - - scipp>=26.3.1 - - scippneutron>=25.11.1 - - scippnexus>=25.6.0 - - graphviz>=0.20 ; extra == 'test' - - ipywidgets>=8.1 ; extra == 'test' - - matplotlib>=3.10.7 ; extra == 'test' - - numba>=0.63 ; extra == 'test' - - pooch>=1.9.0 ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - scipy>=1.14 ; extra == 'test' - - tof>=25.12.0 ; extra == 'test' - - autodoc-pydantic ; extra == 'docs' - - graphviz>=0.20 ; extra == 'docs' - - ipykernel ; extra == 'docs' - - ipython!=8.7.0 ; extra == 'docs' - - ipywidgets>=8.1 ; extra == 'docs' - - myst-parser ; extra == 'docs' - - nbsphinx ; extra == 'docs' - - numba>=0.63 ; extra == 'docs' - - plopp ; extra == 'docs' - - pydata-sphinx-theme>=0.14 ; extra == 'docs' - - sphinx>=7 ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-design ; extra == 'docs' - - tof>=25.12.0 ; extra == 'docs' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda - sha256: 05ffdcb83903c159bfbb78a07fbcce6fd6dda41df9c55ed75e0eb1db5528048f - md5: 879479fda1dddb002fdc4885cea33740 - depends: - - eval_type_backport >=0.2.2,<0.2.3.0a0 - - python >=3.9 - license: MIT - license_family: MIT - purls: [] - size: 6662 - timestamp: 1734857849281 -- conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda - sha256: 2d721421a60676216e10837a240c75e2190e093920a4016a469fa9a62c95ab5f - md5: 8681d7f876da5e66a1c7fce424509383 + - pkg:pypi/annotated-types?source=hash-mapping + size: 18074 + timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + sha256: f09aed24661cd45ba54a43772504f05c0698248734f9ae8cd289d314ac89707e + md5: af2df4b9108808da3dc76710fe50eae2 depends: - - python >=3.9 + - exceptiongroup >=1.0.2 + - idna >=2.8 + - python >=3.10 + - typing_extensions >=4.5 + - python constrains: - - eval-type-backport >=0.2.2,<0.2.3.0a0 + - trio >=0.32.0 + - uvloop >=0.22.1 + - winloop >=0.2.3 license: MIT license_family: MIT purls: - - pkg:pypi/eval-type-backport?source=hash-mapping - size: 11520 - timestamp: 1734857840035 -- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 - md5: 8e662bd460bda79b1ea39194e3c4c9ab + - pkg:pypi/anyio?source=compressed-mapping + size: 146764 + timestamp: 1774359453364 +- conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf + md5: 54898d0f524c9dee622d44bbb081a8ab + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/appnope?source=hash-mapping + size: 10076 + timestamp: 1733332433806 +- conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda + sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad + md5: 8ac12aff0860280ee0cff7fa2cf63f3b + depends: + - argon2-cffi-bindings + - python >=3.9 + - typing-extensions + constrains: + - argon2_cffi ==999 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi?source=hash-mapping + size: 18715 + timestamp: 1749017288144 +- conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda + sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 + md5: 85c4f19f377424eafc4ed7911b291642 depends: - python >=3.10 - - typing_extensions >=4.6.0 - license: MIT and PSF-2.0 + - python-dateutil >=2.7.0 + - python-tzdata + - python + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/exceptiongroup?source=hash-mapping - size: 21333 - timestamp: 1763918099466 -- pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - name: execnet - version: 2.1.2 - sha256: 67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec - requires_dist: - - hatch ; extra == 'testing' - - pre-commit ; extra == 'testing' - - pytest ; extra == 'testing' - - tox ; extra == 'testing' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda - sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad - md5: ff9efb7f7469aed3c4a8106ffa29593c + - pkg:pypi/arrow?source=hash-mapping + size: 113854 + timestamp: 1760831179410 +- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + sha256: ee4da0f3fe9d59439798ee399ef3e482791e48784873d546e706d0935f9ff010 + md5: 9673a61a297b00016442e022d689faa6 + depends: + - python >=3.10 + constrains: + - astroid >=2,<5 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/asttokens?source=hash-mapping + size: 28797 + timestamp: 1763410017955 +- conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda + sha256: ea8486637cfb89dc26dc9559921640cd1d5fd37e5e02c33d85c94572139f2efe + md5: b85e84cb64c762569cc1a760c2327e0a depends: - python >=3.10 + - typing_extensions >=4.0.0 + - python license: MIT license_family: MIT purls: - - pkg:pypi/executing?source=hash-mapping - size: 30753 - timestamp: 1756729456476 -- pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl - name: filelock - version: 3.29.0 - sha256: 96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl - name: fonttools - version: 4.62.1 - sha256: 7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056 - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl - name: fonttools - version: 4.62.1 - sha256: c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79 - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl - name: fonttools - version: 4.62.1 - sha256: 40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7 - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: fonttools - version: 4.62.1 - sha256: 1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl - name: fonttools - version: 4.62.1 - sha256: e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2 - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: fonttools - version: 4.62.1 - sha256: 6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 - requires_dist: - - lxml>=4.0 ; extra == 'lxml' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - - lz4>=1.7.4.2 ; extra == 'graphite' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' - - pycairo ; extra == 'interpolatable' - - matplotlib ; extra == 'plot' - - sympy ; extra == 'symfont' - - xattr ; sys_platform == 'darwin' and extra == 'type1' - - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' - - lxml>=4.0 ; extra == 'all' - - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - - lz4>=1.7.4.2 ; extra == 'all' - - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' - - pycairo ; extra == 'all' - - matplotlib ; extra == 'all' - - sympy ; extra == 'all' - - xattr ; sys_platform == 'darwin' and extra == 'all' - - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.45.0 ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl - name: format-docstring - version: 0.2.7 - sha256: c9d50eafebe0f260e3270ca662ff3a0ed4050f64d95e352f8c5f88d9aede42d6 - requires_dist: - - click>=8.0 - - jupyter-notebook-parser>=0.1.4 - - tomli>=1.1.0 ; python_full_version < '3.11' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda - sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 - md5: d3549fd50d450b6d9e7dddff25dd2110 + - pkg:pypi/async-lru?source=hash-mapping + size: 22949 + timestamp: 1773926359134 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda + sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab + md5: c6b0543676ecb1fb2d7643941fe375f2 depends: - - cached-property >=1.3.0 - - python >=3.9,<4 - license: MPL-2.0 - license_family: MOZILLA + - python >=3.10 + - python + license: MIT + license_family: MIT purls: - - pkg:pypi/fqdn?source=hash-mapping - size: 16705 - timestamp: 1733327494780 -- pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl - name: freetype-py - version: 2.5.1 - sha256: 0b7f8e0342779f65ca13ef8bc103938366fecade23e6bb37cb671c2b8ad7f124 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl - name: frozenlist - version: 1.8.0 - sha256: ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl - name: frozenlist - version: 1.8.0 - sha256: f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: frozenlist - version: 1.8.0 - sha256: 2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl - name: frozenlist - version: 1.8.0 - sha256: fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: frozenlist - version: 1.8.0 - sha256: fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl - name: frozenlist - version: 1.8.0 - sha256: 878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl - name: fsspec - version: 2026.4.0 - sha256: 11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 - requires_dist: - - adlfs ; extra == 'abfs' - - adlfs ; extra == 'adl' - - pyarrow>=1 ; extra == 'arrow' - - dask ; extra == 'dask' - - distributed ; extra == 'dask' - - pre-commit ; extra == 'dev' - - ruff>=0.5 ; extra == 'dev' - - numpydoc ; extra == 'doc' - - sphinx ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - yarl ; extra == 'doc' - - dropbox ; extra == 'dropbox' - - dropboxdrivefs ; extra == 'dropbox' - - requests ; extra == 'dropbox' - - adlfs ; extra == 'full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' - - dask ; extra == 'full' - - distributed ; extra == 'full' - - dropbox ; extra == 'full' - - dropboxdrivefs ; extra == 'full' - - fusepy ; extra == 'full' - - gcsfs>2024.2.0 ; extra == 'full' - - libarchive-c ; extra == 'full' - - ocifs ; extra == 'full' - - panel ; extra == 'full' - - paramiko ; extra == 'full' - - pyarrow>=1 ; extra == 'full' - - pygit2 ; extra == 'full' - - requests ; extra == 'full' - - s3fs>2024.2.0 ; extra == 'full' - - smbprotocol ; extra == 'full' - - tqdm ; extra == 'full' - - fusepy ; extra == 'fuse' - - gcsfs>2024.2.0 ; extra == 'gcs' - - pygit2 ; extra == 'git' - - requests ; extra == 'github' - - gcsfs ; extra == 'gs' - - panel ; extra == 'gui' - - pyarrow>=1 ; extra == 'hdfs' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' - - libarchive-c ; extra == 'libarchive' - - ocifs ; extra == 'oci' - - s3fs>2024.2.0 ; extra == 's3' - - paramiko ; extra == 'sftp' - - smbprotocol ; extra == 'smb' - - paramiko ; extra == 'ssh' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' - - numpy ; extra == 'test' - - pytest ; extra == 'test' - - pytest-asyncio!=0.22.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-recording ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - requests ; extra == 'test' - - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' - - dask[dataframe,test] ; extra == 'test-downstream' - - moto[server]>4,<5 ; extra == 'test-downstream' - - pytest-timeout ; extra == 'test-downstream' - - xarray ; extra == 'test-downstream' - - adlfs ; extra == 'test-full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' - - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' - - cloudpickle ; extra == 'test-full' - - dask ; extra == 'test-full' - - distributed ; extra == 'test-full' - - dropbox ; extra == 'test-full' - - dropboxdrivefs ; extra == 'test-full' - - fastparquet ; extra == 'test-full' - - fusepy ; extra == 'test-full' - - gcsfs ; extra == 'test-full' - - jinja2 ; extra == 'test-full' - - kerchunk ; extra == 'test-full' - - libarchive-c ; extra == 'test-full' - - lz4 ; extra == 'test-full' - - notebook ; extra == 'test-full' - - numpy ; extra == 'test-full' - - ocifs ; extra == 'test-full' - - pandas<3.0.0 ; extra == 'test-full' - - panel ; extra == 'test-full' - - paramiko ; extra == 'test-full' - - pyarrow ; extra == 'test-full' - - pyarrow>=1 ; extra == 'test-full' - - pyftpdlib ; extra == 'test-full' - - pygit2 ; extra == 'test-full' - - pytest ; extra == 'test-full' - - pytest-asyncio!=0.22.0 ; extra == 'test-full' - - pytest-benchmark ; extra == 'test-full' - - pytest-cov ; extra == 'test-full' - - pytest-mock ; extra == 'test-full' - - pytest-recording ; extra == 'test-full' - - pytest-rerunfailures ; extra == 'test-full' - - python-snappy ; extra == 'test-full' - - requests ; extra == 'test-full' - - smbprotocol ; extra == 'test-full' - - tqdm ; extra == 'test-full' - - urllib3 ; extra == 'test-full' - - zarr ; extra == 'test-full' - - zstandard ; python_full_version < '3.14' and extra == 'test-full' - - tqdm ; extra == 'tqdm' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda - sha256: 4a3e3e86b7b49aaa2a0faa57da2bcf39f7ee858499e8335132f83bfeed79191e - md5: 84f8955e99a8944fdee49da39edb0add + - pkg:pypi/attrs?source=hash-mapping + size: 64927 + timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda + sha256: a14a9ad02101aab25570543a59c5193043b73dc311a25650134ed9e6cb691770 + md5: f1976ce927373500cc19d3c0b2c85177 depends: - - python >=3.9 + - python >=3.10 + - python + constrains: + - pytz >=2015.7 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/funcy?source=hash-mapping - size: 30249 - timestamp: 1734381235500 -- pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: gemmi - version: 0.7.5 - sha256: 750b4d9751aaf1460ac4f0f45308ddced25f47bcf7a30355eb3b1f779f03952a - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl - name: gemmi - version: 0.7.5 - sha256: c7d8b08c33fe6ba375223306149092440c69cbfbd55c3d3e3436e5fb315a225d - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl - name: gemmi - version: 0.7.5 - sha256: ad1f72ffa24adbfaf259e11471f6f071a668667f6ca846051f3bfea024fd337d - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl - name: ghp-import - version: 2.1.0 - sha256: 8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 - requires_dist: - - python-dateutil>=2.8.1 - - twine ; extra == 'dev' - - markdown ; extra == 'dev' - - flake8 ; extra == 'dev' - - wheel ; extra == 'dev' -- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - name: gitdb - version: 4.0.12 - sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf - requires_dist: - - smmap>=3.0.1,<6 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl - name: gitpython - version: 3.1.50 - sha256: d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 - requires_dist: - - gitdb>=4.0.1,<5 - - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' - - coverage[toml] ; extra == 'test' - - ddt>=1.1.1,!=1.4.3 ; extra == 'test' - - mock ; python_full_version < '3.8' and extra == 'test' - - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' - - pre-commit ; extra == 'test' - - pytest>=7.3.1 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-instafail ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-sugar ; extra == 'test' - - typing-extensions ; python_full_version < '3.11' and extra == 'test' - - sphinx>=7.4.7,<8 ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - sphinx-autodoc-typehints ; extra == 'doc' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl - name: graphviz - version: '0.21' - sha256: 54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42 - requires_dist: - - build ; extra == 'dev' - - wheel ; extra == 'dev' - - twine ; extra == 'dev' - - flake8 ; extra == 'dev' - - flake8-pyproject ; extra == 'dev' - - pep8-naming ; extra == 'dev' - - tox>=3 ; extra == 'dev' - - pytest>=7,<8.1 ; extra == 'test' - - pytest-mock>=3 ; extra == 'test' - - pytest-cov ; extra == 'test' - - coverage ; extra == 'test' - - sphinx>=5,<7 ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx-rtd-theme>=0.2.5 ; extra == 'docs' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: greenlet - version: 3.5.0 - sha256: 2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl - name: greenlet - version: 3.5.0 - sha256: 728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl - name: griffelib - version: 2.0.2 - sha256: 925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1 - requires_dist: - - pip>=24.0 ; extra == 'pypi' - - platformdirs>=4.2 ; extra == 'pypi' - - wheel>=0.42 ; extra == 'pypi' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda - sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb - md5: b8993c19b0c32a2f7b66cbb58ca27069 + - pkg:pypi/babel?source=compressed-mapping + size: 7684321 + timestamp: 1772555330347 +- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda + sha256: bf1e71c3c0a5b024e44ff928225a0874fc3c3356ec1a0b6fe719108e6d1288f6 + md5: 5267bef8efea4127aacd1f4e1f149b6e depends: - python >=3.10 - - typing_extensions - - python + - soupsieve >=1.2 + - typing-extensions license: MIT license_family: MIT purls: - - pkg:pypi/h11?source=compressed-mapping - size: 39069 - timestamp: 1767729720872 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 - md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 + - pkg:pypi/beautifulsoup4?source=hash-mapping + size: 90399 + timestamp: 1764520638652 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda + sha256: f8ff1f98423674278964a46c93a1766f9e91960d44efd91c6c3ed56a33813f46 + md5: 7c5ebdc286220e8021bf55e6384acd67 depends: - python >=3.10 - - hyperframe >=6.1,<7 - - hpack >=4.1,<5 + - webencodings - python - license: MIT - license_family: MIT + constrains: + - tinycss2 >=1.1.0,<1.5 + license: Apache-2.0 AND MIT purls: - - pkg:pypi/h2?source=hash-mapping - size: 95967 - timestamp: 1756364871835 -- pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl - name: h5py - version: 3.16.0 - sha256: fb1720028d99040792bb2fb31facb8da44a6f29df7697e0b84f0d79aff2e9bd3 - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl - name: h5py - version: 3.16.0 - sha256: 42108e93326c50c2810025aade9eac9d6827524cdccc7d4b75a546e5ab308edb - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl - name: h5py - version: 3.16.0 - sha256: 9300ad32dea9dfc5171f94d5f6948e159ed93e4701280b0f508773b3f582f402 - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl - name: h5py - version: 3.16.0 - sha256: c3f0a0e136f2e95dd0b67146abb6668af4f1a69c81ef8651a2d316e8e01de447 - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl - name: h5py - version: 3.16.0 - sha256: 18f2bbcd545e6991412253b98727374c356d67caa920e68dc79eab36bf5fedad - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl - name: h5py - version: 3.16.0 - sha256: 17d1f1630f92ad74494a9a7392ab25982ce2b469fc62da6074c0ce48366a2999 - requires_dist: - - numpy>=1.21.2 - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba - md5: 0a802cb9888dd14eeefc611f05c40b6e + - pkg:pypi/bleach?source=hash-mapping + size: 142008 + timestamp: 1770719370680 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda + sha256: 7c07a865e5e4cca233cc4e0eb3f0f5ff6c90776461687b4fb0b1764133e1fd61 + md5: f11a319b9700b203aa14c295858782b6 depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/hpack?source=hash-mapping - size: 30731 - timestamp: 1737618390337 -- pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl - name: html5lib - version: '1.1' - sha256: 0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d - requires_dist: - - six>=1.9 - - webencodings - - genshi ; extra == 'all' - - chardet>=2.2 ; extra == 'all' - - lxml ; platform_python_implementation == 'CPython' and extra == 'all' - - chardet>=2.2 ; extra == 'chardet' - - genshi ; extra == 'genshi' - - lxml ; platform_python_implementation == 'CPython' and extra == 'lxml' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b - md5: 4f14640d58e2cc0aa0819d9d8ba125bb + - bleach ==6.3.0 pyhcf101f3_1 + - tinycss2 + license: Apache-2.0 AND MIT + purls: [] + size: 4409 + timestamp: 1770719370682 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda + sha256: 6f4ff81534c19e76acf52fcabf4a258088a932b8f1ac56e9a59e98f6051f8e46 + md5: 56fb2c6c73efc627b40c77d14caecfba depends: - - python >=3.9 - - h11 >=0.16 - - h2 >=3,<5 - - sniffio 1.* - - anyio >=4.0,<5.0 - - certifi - - python + - __win + license: ISC + purls: [] + size: 131388 + timestamp: 1776865633471 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda + sha256: c9dbcc8039a52023660d6d1bbf87594a93dd69c6ac5a2a44323af2c92976728d + md5: e18ad67cf881dcadee8b8d9e2f8e5f73 + depends: + - __unix + license: ISC + purls: [] + size: 131039 + timestamp: 1776865545798 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 + noarch: python + sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 + md5: 9b347a7ec10940d3f7941ff6c460b551 + depends: + - cached_property >=1.5.2,<1.5.3.0a0 license: BSD-3-Clause license_family: BSD - purls: - - pkg:pypi/httpcore?source=hash-mapping - size: 49483 - timestamp: 1745602916758 -- conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 - md5: d6989ead454181f4f9bc987d3dc4e285 + purls: [] + size: 4134 + timestamp: 1615209571450 +- conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + sha256: 6dbf7a5070cc43d90a1e4c2ec0c541c69d8e30a0e25f50ce9f6e4a432e42c5d7 + md5: 576d629e47797577ab0f1b351297ef4a depends: - - anyio - - certifi - - httpcore 1.* - - idna - - python >=3.9 + - python >=3.6 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/httpx?source=hash-mapping - size: 63082 - timestamp: 1733663449209 -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 - md5: 8e6923fc12f1fe8f8c4e5c9f343256ac + - pkg:pypi/cached-property?source=hash-mapping + size: 11065 + timestamp: 1615209567874 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda + sha256: 989db6e5957c4b44fa600c68c681ec2f36a55e48f7c7f1c073d5e91caa8cd878 + md5: 929471569c93acefb30282a22060dcd5 depends: - - python >=3.9 - license: MIT - license_family: MIT + - python >=3.10 + license: ISC purls: - - pkg:pypi/hyperframe?source=hash-mapping - size: 17397 - timestamp: 1737618427549 -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a - md5: c80d8a3b84358cb967fa81e7075fbc8a + - pkg:pypi/certifi?source=compressed-mapping + size: 135656 + timestamp: 1776866680878 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda + sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 + md5: a9167b9571f3baa9d448faa2139d1089 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 + - python >=3.10 license: MIT license_family: MIT - purls: [] - size: 12723451 - timestamp: 1773822285671 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5 - md5: f1182c91c0de31a7abd40cedf6a5ebef + purls: + - pkg:pypi/charset-normalizer?source=compressed-mapping + size: 58872 + timestamp: 1775127203018 +- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 + md5: 962b9857ee8e7018c22f2776ffa0b2d7 depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 12361647 - timestamp: 1773822915649 -- pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl - name: identify - version: 2.6.19 - sha256: 20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a - requires_dist: - - ukkonen ; extra == 'license' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda - sha256: 9ab620e6f64bb67737bd7bc1ad6f480770124e304c6710617aba7fe60b089f48 - md5: fb7130c190f9b4ec91219840a05ba3ac + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/colorama?source=hash-mapping + size: 27011 + timestamp: 1733218222191 +- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 + md5: 2da13f2b299d8e1995bafbbe9689a2f7 depends: - - python >=3.10 + - python >=3.9 - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/idna?source=compressed-mapping - size: 59038 - timestamp: 1776947141407 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda - sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 - md5: 080594bf4493e6bae2607e65390c520a + - pkg:pypi/comm?source=hash-mapping + size: 14690 + timestamp: 1753453984907 +- conda: https://conda.anaconda.org/conda-forge/noarch/copier-9.15.0-pyhcf101f3_0.conda + sha256: 2ceb1f7edb5e5943f7af69e4d6b3339b2e2580e7c9eef76efed4d18d05ae49db + md5: 12baf87bfa62ac066dbe2526f5d89de1 depends: - python >=3.10 - - zipp >=3.20 + - colorama >=0.4.6 + - dunamai >=1.7.0 + - funcy >=1.17 + - jinja2 >=3.1.5 + - jinja2-ansible-filters >=1.3.1 + - packaging >=23.0 + - pathspec >=0.9.0 + - plumbum >=1.6.9 + - prompt-toolkit <3.0.52 + - pydantic >=2.4.2 + - pygments >=2.7.1 + - pyyaml >=5.3.1 + - questionary >=1.8.1 + - eval-type-backport >=0.1.3,<0.3.0 + - platformdirs >=4.3.6 + - typing_extensions >=4.0.0,<5.0.0 - python - license: Apache-2.0 - license_family: APACHE + license: MIT + license_family: MIT purls: - - pkg:pypi/importlib-metadata?source=compressed-mapping - size: 34387 - timestamp: 1773931568510 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda - sha256: a563a51aa522998172838e867e6dedcf630bc45796e8612f5a1f6d73e9c8125a - md5: 0ba6225c279baf7ea9473a62ea0ec9ae + - pkg:pypi/copier?source=hash-mapping + size: 58609 + timestamp: 1777562504238 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.13-py313hd8ed1ab_100.conda + noarch: generic + sha256: 836b92c209d4b6b9fb28bd51bd788b22a0c5492ae95eec2724e65a15ed4ab2e1 + md5: 3a8a8b87e72f95b54689fb588e154ec9 depends: - - python >=3.10 - - zipp >=3.1.0 - constrains: - - importlib-resources >=7.1.0,<7.1.1.0a0 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/importlib-resources?source=compressed-mapping - size: 34809 - timestamp: 1776068839274 -- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - name: iniconfig - version: 2.3.0 - sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl - name: interrogate - version: 1.7.0 - sha256: b13ff4dd8403369670e2efe684066de9fcb868ad9d7f2b4095d8112142dc9d12 - requires_dist: - - attrs - - click>=7.1 - - colorama - - py - - tabulate - - tomli ; python_full_version < '3.11' - - cairosvg ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-autobuild ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-mock ; extra == 'dev' - - coverage[toml] ; extra == 'dev' - - wheel ; extra == 'dev' - - pre-commit ; extra == 'dev' - - sphinx ; extra == 'docs' - - sphinx-autobuild ; extra == 'docs' - - cairosvg ; extra == 'png' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-mock ; extra == 'tests' - - coverage[toml] ; extra == 'tests' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda - sha256: d7421c54944dec04d2671e23196a15583d48f309d06fbcf995b5dfa6d586a5e9 - md5: 4dee387356d58bdc4b686ae3424fbd9e + - python >=3.13,<3.14.0a0 + - python_abi * *_cp313 + license: Python-2.0 + purls: [] + size: 48530 + timestamp: 1775613723457 +- conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 + md5: 9ce473d1d1be1cc3810856a48b3fab32 depends: - - python >=3.10 + - python >=3.9 license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/invoke?source=hash-mapping - size: 133811 - timestamp: 1775579645825 -- pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl - name: ipydatawidgets - version: 4.3.5 - sha256: d590cdb7c364f2f6ab346f20b9d2dd661d27a834ef7845bc9d7113118f05ec87 - requires_dist: - - ipywidgets>=7.0.0 - - numpy - - traittypes>=0.2.0 - - sphinx ; extra == 'docs' - - recommonmark ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - pytest>=4 ; extra == 'test' - - pytest-cov ; extra == 'test' - - nbval>=0.9.2 ; extra == 'test' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda - sha256: 5c1f3e874adaf603449f2b135d48f168c5d510088c78c229bda0431268b43b27 - md5: 4b53d436f3fbc02ce3eeaf8ae9bebe01 + - pkg:pypi/decorator?source=hash-mapping + size: 14129 + timestamp: 1740385067843 +- conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + sha256: 9717a059677553562a8f38ff07f3b9f61727bd614f505658b0a5ecbcf8df89be + md5: 961b3a227b437d82ad7054484cfa71b2 depends: - - appnope - - __osx - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD + - python >=3.6 + license: PSF-2.0 + license_family: PSF purls: - - pkg:pypi/ipykernel?source=hash-mapping - size: 132260 - timestamp: 1770566135697 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda - sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 - md5: b3a7d5842f857414d9ae831a799444dd + - pkg:pypi/defusedxml?source=hash-mapping + size: 24062 + timestamp: 1615232388757 +- conda: https://conda.anaconda.org/conda-forge/noarch/dunamai-1.26.1-pyhd8ed1ab_0.conda + sha256: 930f21584babebdabc8310f894557d032211f6cb427f7028c7c92cab6fe6cc1f + md5: dbb824a3a87ac1e2ce02f8227be67e74 depends: - - __win - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 + - importlib-metadata >=1.6.0 + - packaging >=20.9 - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD + license: MIT + license_family: MIT purls: - - pkg:pypi/ipykernel?source=hash-mapping - size: 132382 - timestamp: 1770566174387 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda - sha256: b77ed58eb235e5ad80e742b03caeed4bbc2a2ef064cb9a2deee3b75dfae91b2a - md5: 8b267f517b81c13594ed68d646fd5dcb + - pkg:pypi/dunamai?source=hash-mapping + size: 30866 + timestamp: 1775597880526 +- conda: https://conda.anaconda.org/conda-forge/noarch/eval-type-backport-0.2.2-pyhd8ed1ab_0.conda + sha256: 05ffdcb83903c159bfbb78a07fbcce6fd6dda41df9c55ed75e0eb1db5528048f + md5: 879479fda1dddb002fdc4885cea33740 depends: - - __linux - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipykernel?source=hash-mapping - size: 133644 - timestamp: 1770566133040 -- pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl - name: ipympl - version: 0.10.0 - sha256: a09c4f0ff86490cc62aed45e53b912fb706e3ec3506c4a51ce4a670d6667f5ce - requires_dist: - - ipython<10 - - ipywidgets>=7.6.0,<9 - - matplotlib>=3.5.0,<4 - - numpy - - pillow - - traitlets<6 - - intersphinx-registry ; extra == 'docs' - - myst-nb ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-thebe ; extra == 'docs' - - sphinx-togglebutton ; extra == 'docs' - - sphinx>=1.5 ; extra == 'docs' - - nbval>=0.11.0 ; extra == 'test' - - pytest>=9.0.2 ; extra == 'test' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda - sha256: a0af49948a1842dfd15a0b0b2fd56c94ddbd07e07a6c8b4bc70d43015eafaff0 - md5: 73e9657cd19605740d21efb14d8d0cb9 - depends: - - __unix - - decorator >=5.1.0 - - ipython_pygments_lexers >=1.0.0 - - jedi >=0.18.2 - - matplotlib-inline >=0.1.6 - - prompt-toolkit >=3.0.41,<3.1.0 - - psutil >=7 - - pygments >=2.14.0 - - python >=3.11 - - stack_data >=0.6.0 - - traitlets >=5.13.0 - - typing_extensions >=4.6 - - pexpect >4.6 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython?source=compressed-mapping - size: 651632 - timestamp: 1777038396606 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda - sha256: f252ec33597115ff21cbb31051f6f9be34ca36cbbbf3d266b597660d8d8edde9 - md5: 5631ab99e902463d9dd4221e5b4eab6d - depends: - - __win - - decorator >=5.1.0 - - ipython_pygments_lexers >=1.0.0 - - jedi >=0.18.2 - - matplotlib-inline >=0.1.6 - - prompt-toolkit >=3.0.41,<3.1.0 - - psutil >=7 - - pygments >=2.14.0 - - python >=3.11 - - stack_data >=0.6.0 - - traitlets >=5.13.0 - - typing_extensions >=4.6 - - colorama >=0.4.4 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython?source=compressed-mapping - size: 650593 - timestamp: 1777038425499 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 - md5: bd80ba060603cc228d9d81c257093119 - depends: - - pygments - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython-pygments-lexers?source=hash-mapping - size: 13993 - timestamp: 1737123723464 -- pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - name: ipywidgets - version: 8.1.8 - sha256: ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e - requires_dist: - - comm>=0.1.3 - - ipython>=6.1.0 - - traitlets>=4.3.1 - - widgetsnbextension~=4.0.14 - - jupyterlab-widgets~=3.0.15 - - jsonschema ; extra == 'test' - - ipykernel ; extra == 'test' - - pytest>=3.6.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytz ; extra == 'test' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda - sha256: 08e838d29c134a7684bca0468401d26840f41c92267c4126d7b43a6b533b0aed - md5: 0b0154421989637d424ccf0f104be51a - depends: - - arrow >=0.15.0 + - eval_type_backport >=0.2.2,<0.2.3.0a0 - python >=3.9 license: MIT license_family: MIT - purls: - - pkg:pypi/isoduration?source=hash-mapping - size: 19832 - timestamp: 1733493720346 -- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 - md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 + purls: [] + size: 6662 + timestamp: 1734857849281 +- conda: https://conda.anaconda.org/conda-forge/noarch/eval_type_backport-0.2.2-pyha770c72_0.conda + sha256: 2d721421a60676216e10837a240c75e2190e093920a4016a469fa9a62c95ab5f + md5: 8681d7f876da5e66a1c7fce424509383 depends: - - parso >=0.8.3,<0.9.0 - python >=3.9 - license: Apache-2.0 AND MIT + constrains: + - eval-type-backport >=0.2.2,<0.2.3.0a0 + license: MIT + license_family: MIT purls: - - pkg:pypi/jedi?source=hash-mapping - size: 843646 - timestamp: 1733300981994 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b - md5: 04558c96691bed63104678757beb4f8d + - pkg:pypi/eval-type-backport?source=hash-mapping + size: 11520 + timestamp: 1734857840035 +- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 + md5: 8e662bd460bda79b1ea39194e3c4c9ab depends: - - markupsafe >=2.0 - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD + - typing_extensions >=4.6.0 + license: MIT and PSF-2.0 purls: - - pkg:pypi/jinja2?source=compressed-mapping - size: 120685 - timestamp: 1764517220861 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda - sha256: a36789229ca9ce5315265b9d425abce9acb4691f5864aea69e935020545a9acb - md5: 974c5b3e353f031cfcf2365c9d375926 + - pkg:pypi/exceptiongroup?source=hash-mapping + size: 21333 + timestamp: 1763918099466 +- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad + md5: ff9efb7f7469aed3c4a8106ffa29593c depends: - - jinja2 - - python >=3.9 - - pyyaml - license: BSD-2-Clause - license_family: BSD + - python >=3.10 + license: MIT + license_family: MIT purls: - - pkg:pypi/jinja2-ansible-filters?source=hash-mapping - size: 20315 - timestamp: 1734906203051 -- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda - sha256: 9daa95bd164c8fa23b3ab196e906ef806141d749eddce2a08baa064f722d25fa - md5: 1269891272187518a0a75c286f7d0bbf + - pkg:pypi/executing?source=hash-mapping + size: 30753 + timestamp: 1756729456476 +- conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda + sha256: 2509992ec2fd38ab27c7cdb42cf6cadc566a1cc0d1021a2673475d9fa87c6276 + md5: d3549fd50d450b6d9e7dddff25dd2110 depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE + - cached-property >=1.3.0 + - python >=3.9,<4 + license: MPL-2.0 + license_family: MOZILLA purls: - - pkg:pypi/json5?source=compressed-mapping - size: 34731 - timestamp: 1774655440045 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda - sha256: a3d10301b6ff399ba1f3d39e443664804a3d28315a4fb81e745b6817845f70ae - md5: 89bf346df77603055d3c8fe5811691e6 + - pkg:pypi/fqdn?source=hash-mapping + size: 16705 + timestamp: 1733327494780 +- conda: https://conda.anaconda.org/conda-forge/noarch/funcy-2.0-pyhd8ed1ab_1.conda + sha256: 4a3e3e86b7b49aaa2a0faa57da2bcf39f7ee858499e8335132f83bfeed79191e + md5: 84f8955e99a8944fdee49da39edb0add depends: - - python >=3.10 - - python + - python >=3.9 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jsonpointer?source=hash-mapping - size: 14190 - timestamp: 1774311356147 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda - sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 - md5: ada41c863af263cc4c5fcbaff7c3e4dc + - pkg:pypi/funcy?source=hash-mapping + size: 30249 + timestamp: 1734381235500 +- conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.16.0-pyhcf101f3_1.conda + sha256: 96cac6573fd35ae151f4d6979bab6fbc90cb6b1fb99054ba19eb075da9822fcb + md5: b8993c19b0c32a2f7b66cbb58ca27069 depends: - - attrs >=22.2.0 - - jsonschema-specifications >=2023.3.6 - python >=3.10 - - referencing >=0.28.4 - - rpds-py >=0.25.0 + - typing_extensions - python license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema?source=hash-mapping - size: 82356 - timestamp: 1767839954256 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 - md5: 439cd0f567d697b20a8f45cb70a1005a + - pkg:pypi/h11?source=compressed-mapping + size: 39069 + timestamp: 1767729720872 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 + md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 depends: - python >=3.10 - - referencing >=0.31.0 + - hyperframe >=6.1,<7 + - hpack >=4.1,<5 - python license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema-specifications?source=hash-mapping - size: 19236 - timestamp: 1757335715225 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda - sha256: 6886fc61e4e4edd38fd38729976b134e8bd2143f7fce56cc80d7ac7bac99bce1 - md5: 8368d58342d0825f0843dc6acdd0c483 + - pkg:pypi/h2?source=hash-mapping + size: 95967 + timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba + md5: 0a802cb9888dd14eeefc611f05c40b6e depends: - - jsonschema >=4.26.0,<4.26.1.0a0 - - fqdn - - idna - - isoduration - - jsonpointer >1.13 - - rfc3339-validator - - rfc3986-validator >0.1.0 - - rfc3987-syntax >=1.1.0 - - uri-template - - webcolors >=24.6.0 + - python >=3.9 license: MIT license_family: MIT - purls: [] - size: 4740 - timestamp: 1767839954258 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda - sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e - md5: 0c3b465ceee138b9c39279cc02e5c4a0 + purls: + - pkg:pypi/hpack?source=hash-mapping + size: 30731 + timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda + sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b + md5: 4f14640d58e2cc0aa0819d9d8ba125bb depends: - - importlib-metadata >=4.8.3 - - jupyter_server >=1.1.2 - - python >=3.10 + - python >=3.9 + - h11 >=0.16 + - h2 >=3,<5 + - sniffio 1.* + - anyio >=4.0,<5.0 + - certifi - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-lsp?source=compressed-mapping - size: 61633 - timestamp: 1775136333147 -- pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl - name: jupyter-notebook-parser - version: 0.1.4 - sha256: 27b3b67cf898684e646d569f017cb27046774ad23866cb0bdf51d5f76a46476b - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda - sha256: e402bd119720862a33229624ec23645916a7d47f30e1711a4af9e005162b84f3 - md5: 8a3d6d0523f66cf004e563a50d9392b3 + - pkg:pypi/httpcore?source=hash-mapping + size: 49483 + timestamp: 1745602916758 +- conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda + sha256: cd0f1de3697b252df95f98383e9edb1d00386bfdd03fdf607fa42fe5fcb09950 + md5: d6989ead454181f4f9bc987d3dc4e285 depends: - - jupyter_core >=5.1 - - python >=3.10 - - python-dateutil >=2.8.2 - - pyzmq >=25.0 - - tornado >=6.4.1 - - traitlets >=5.3 - - python + - anyio + - certifi + - httpcore 1.* + - idna + - python >=3.9 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-client?source=hash-mapping - size: 112785 - timestamp: 1767954655912 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc - md5: a8db462b01221e9f5135be466faeb3e0 + - pkg:pypi/httpx?source=hash-mapping + size: 63082 + timestamp: 1733663449209 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 + md5: 8e6923fc12f1fe8f8c4e5c9f343256ac + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hyperframe?source=hash-mapping + size: 17397 + timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda + sha256: 9ab620e6f64bb67737bd7bc1ad6f480770124e304c6710617aba7fe60b089f48 + md5: fb7130c190f9b4ec91219840a05ba3ac depends: - - __win - - pywin32 - - platformdirs >=2.5 - python >=3.10 - - traitlets >=5.3 - python - constrains: - - pywin32 >=300 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-core?source=hash-mapping - size: 64679 - timestamp: 1760643889625 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a - md5: b38fe4e78ee75def7e599843ef4c1ab0 + - pkg:pypi/idna?source=compressed-mapping + size: 59038 + timestamp: 1776947141407 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda + sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16 + md5: 080594bf4493e6bae2607e65390c520a depends: - - __unix - - python - - platformdirs >=2.5 - python >=3.10 - - traitlets >=5.3 + - zipp >=3.20 - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/importlib-metadata?source=compressed-mapping + size: 34387 + timestamp: 1773931568510 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda + sha256: a563a51aa522998172838e867e6dedcf630bc45796e8612f5a1f6d73e9c8125a + md5: 0ba6225c279baf7ea9473a62ea0ec9ae + depends: + - python >=3.10 + - zipp >=3.1.0 constrains: - - pywin32 >=300 - license: BSD-3-Clause - license_family: BSD + - importlib-resources >=7.1.0,<7.1.1.0a0 + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/jupyter-core?source=hash-mapping - size: 65503 - timestamp: 1760643864586 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda - sha256: c7edb5682c6316a95ad781dccb1b6589cd2ec0bf94f23c21152974eb0363b5d7 - md5: bf42ee94c750c0b2e7e998b79ac299ea + - pkg:pypi/importlib-resources?source=compressed-mapping + size: 34809 + timestamp: 1776068839274 +- conda: https://conda.anaconda.org/conda-forge/noarch/invoke-3.0.3-pyhd8ed1ab_0.conda + sha256: d7421c54944dec04d2671e23196a15583d48f309d06fbcf995b5dfa6d586a5e9 + md5: 4dee387356d58bdc4b686ae3424fbd9e depends: - - jsonschema-with-format-nongpl >=4.18.0 - - packaging - python >=3.10 - - python-json-logger >=2.0.4 - - pyyaml >=5.3 - - referencing - - rfc3339-validator - - rfc3986-validator >=0.1.1 - - traitlets >=5.3 - - python - license: BSD-3-Clause + license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/jupyter-events?source=compressed-mapping - size: 24002 - timestamp: 1776861872237 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda - sha256: 04fb8ea7749f67abaf76df6257bf86688e1389ceed55eb4fb0176fd2e882dbd6 - md5: 5ee7945accf0f215ddd6055d25d7cd83 + - pkg:pypi/invoke?source=hash-mapping + size: 133811 + timestamp: 1775579645825 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + sha256: 5c1f3e874adaf603449f2b135d48f168c5d510088c78c229bda0431268b43b27 + md5: 4b53d436f3fbc02ce3eeaf8ae9bebe01 depends: - - anyio >=3.1.0 - - argon2-cffi >=21.1 - - jinja2 >=3.0.3 - - jupyter_client >=7.4.4 - - jupyter_core >=4.12,!=5.0.* - - jupyter_events >=0.11.0 - - jupyter_server_terminals >=0.4.4 - - nbconvert-core >=6.4.4 - - nbformat >=5.3.0 - - overrides >=5.0 - - packaging >=22.0 - - prometheus_client >=0.9 + - appnope + - __osx + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 - python >=3.10 - - pyzmq >=24 - - send2trash >=1.8.2 - - terminado >=0.8.3 - - tornado >=6.2.0 - - traitlets >=5.6.0 - - websocket-client >=1.7 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/jupyter-server?source=compressed-mapping - size: 360522 - timestamp: 1778060967727 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda - sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 - md5: 7b8bace4943e0dc345fc45938826f2b8 + - pkg:pypi/ipykernel?source=hash-mapping + size: 132260 + timestamp: 1770566135697 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 + md5: b3a7d5842f857414d9ae831a799444dd depends: + - __win + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 - python >=3.10 - - terminado >=0.8.3 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-server-terminals?source=hash-mapping - size: 22052 - timestamp: 1768574057200 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - sha256: b85befad5ba1f50c0cc042a2ffb26441d13ffc2f18572dc20d3541476da0c7b9 - md5: 2ffe77234070324e763a6eddabb5f467 + - pkg:pypi/ipykernel?source=hash-mapping + size: 132382 + timestamp: 1770566174387 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + sha256: b77ed58eb235e5ad80e742b03caeed4bbc2a2ef064cb9a2deee3b75dfae91b2a + md5: 8b267f517b81c13594ed68d646fd5dcb depends: - - async-lru >=1.0.0 - - httpx >=0.25.0,<1 - - ipykernel >=6.5.0,!=6.30.0 - - jinja2 >=3.0.3 - - jupyter-lsp >=2.0.0 - - jupyter_core - - jupyter_server >=2.4.0,<3 - - jupyterlab_server >=2.28.0,<3 - - notebook-shim >=0.2 - - packaging + - __linux + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 - python >=3.10 - - setuptools >=41.1.0 - - tomli >=1.2.2 - - tornado >=6.2.0 - - traitlets + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab?source=compressed-mapping - size: 8861204 - timestamp: 1777483115382 -- pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl - name: jupyterlab-widgets - version: 3.0.16 - sha256: 45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 - md5: fd312693df06da3578383232528c468d + - pkg:pypi/ipykernel?source=hash-mapping + size: 133644 + timestamp: 1770566133040 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + sha256: a0af49948a1842dfd15a0b0b2fd56c94ddbd07e07a6c8b4bc70d43015eafaff0 + md5: 73e9657cd19605740d21efb14d8d0cb9 depends: - - pygments >=2.4.1,<3 - - python >=3.9 - constrains: - - jupyterlab >=4.0.8,<5.0.0 + - __unix + - decorator >=5.1.0 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.2 + - matplotlib-inline >=0.1.6 + - prompt-toolkit >=3.0.41,<3.1.0 + - psutil >=7 + - pygments >=2.14.0 + - python >=3.11 + - stack_data >=0.6.0 + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - pexpect >4.6 + - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab-pygments?source=hash-mapping - size: 18711 - timestamp: 1733328194037 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee - md5: a63877cb23de826b1620d3adfccc4014 + - pkg:pypi/ipython?source=compressed-mapping + size: 651632 + timestamp: 1777038396606 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyhe2676ad_0.conda + sha256: f252ec33597115ff21cbb31051f6f9be34ca36cbbbf3d266b597660d8d8edde9 + md5: 5631ab99e902463d9dd4221e5b4eab6d depends: - - babel >=2.10 - - jinja2 >=3.0.3 - - json5 >=0.9.0 - - jsonschema >=4.18 - - jupyter_server >=1.21,<3 - - packaging >=21.3 - - python >=3.10 - - requests >=2.31 + - __win + - decorator >=5.1.0 + - ipython_pygments_lexers >=1.0.0 + - jedi >=0.18.2 + - matplotlib-inline >=0.1.6 + - prompt-toolkit >=3.0.41,<3.1.0 + - psutil >=7 + - pygments >=2.14.0 + - python >=3.11 + - stack_data >=0.6.0 + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - colorama >=0.4.4 - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab-server?source=hash-mapping - size: 51621 - timestamp: 1761145478692 -- pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl - name: jupyterquiz - version: 2.9.6.4 - sha256: f8c4418f6c827454523fc882a30d744b585cb58ac1ae277769c3059d04fc272b -- pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - name: jupytext - version: 1.19.1 - sha256: d8975035155d034bdfde5c0c37891425314b7ea8d3a6c4b5d18c294348714cd9 - requires_dist: - - markdown-it-py>=1.0 - - mdit-py-plugins - - nbformat - - packaging - - pyyaml - - tomli ; python_full_version < '3.11' - - autopep8 ; extra == 'dev' - - black ; extra == 'dev' - - flake8 ; extra == 'dev' - - gitpython ; extra == 'dev' - - ipykernel ; extra == 'dev' - - isort ; extra == 'dev' - - jupyter-fs[fs]>=1.0 ; extra == 'dev' - - jupyter-server!=2.11 ; extra == 'dev' - - marimo>=0.17.6,<=0.19.4 ; extra == 'dev' - - nbconvert ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-asyncio ; extra == 'dev' - - pytest-cov>=2.6.1 ; extra == 'dev' - - pytest-randomly ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-gallery>=0.8 ; extra == 'dev' - - myst-parser ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-randomly ; extra == 'test' - - pytest-xdist ; extra == 'test' - - black ; extra == 'test-cov' - - ipykernel ; extra == 'test-cov' - - jupyter-server!=2.11 ; extra == 'test-cov' - - nbconvert ; extra == 'test-cov' - - pytest ; extra == 'test-cov' - - pytest-asyncio ; extra == 'test-cov' - - pytest-cov>=2.6.1 ; extra == 'test-cov' - - pytest-randomly ; extra == 'test-cov' - - pytest-xdist ; extra == 'test-cov' - - autopep8 ; extra == 'test-external' - - black ; extra == 'test-external' - - flake8 ; extra == 'test-external' - - gitpython ; extra == 'test-external' - - ipykernel ; extra == 'test-external' - - isort ; extra == 'test-external' - - jupyter-fs[fs]>=1.0 ; extra == 'test-external' - - jupyter-server!=2.11 ; extra == 'test-external' - - marimo>=0.17.6,<=0.19.4 ; extra == 'test-external' - - nbconvert ; extra == 'test-external' - - pre-commit ; extra == 'test-external' - - pytest ; extra == 'test-external' - - pytest-asyncio ; extra == 'test-external' - - pytest-randomly ; extra == 'test-external' - - pytest-xdist ; extra == 'test-external' - - sphinx ; extra == 'test-external' - - sphinx-gallery>=0.8 ; extra == 'test-external' - - black ; extra == 'test-functional' - - pytest ; extra == 'test-functional' - - pytest-asyncio ; extra == 'test-functional' - - pytest-randomly ; extra == 'test-functional' - - pytest-xdist ; extra == 'test-functional' - - black ; extra == 'test-integration' - - ipykernel ; extra == 'test-integration' - - jupyter-server!=2.11 ; extra == 'test-integration' - - nbconvert ; extra == 'test-integration' - - pytest ; extra == 'test-integration' - - pytest-asyncio ; extra == 'test-integration' - - pytest-randomly ; extra == 'test-integration' - - pytest-xdist ; extra == 'test-integration' - - bash-kernel ; extra == 'test-ui' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 - md5: b38117a3c920364aff79f870c984b4a3 + - pkg:pypi/ipython?source=compressed-mapping + size: 650593 + timestamp: 1777038425499 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda + sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 + md5: bd80ba060603cc228d9d81c257093119 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-or-later - purls: [] - size: 134088 - timestamp: 1754905959823 -- pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl - name: kiwisolver - version: 1.5.0 - sha256: 0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: kiwisolver - version: 1.5.0 - sha256: 332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: kiwisolver - version: 1.5.0 - sha256: 2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl - name: kiwisolver - version: 1.5.0 - sha256: dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl - name: kiwisolver - version: 1.5.0 - sha256: beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl - name: kiwisolver - version: 1.5.0 - sha256: 0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 - md5: fb53fb07ce46a575c5d004bbc96032c2 + - pygments + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython-pygments-lexers?source=hash-mapping + size: 13993 + timestamp: 1737123723464 +- conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda + sha256: 08e838d29c134a7684bca0468401d26840f41c92267c4126d7b43a6b533b0aed + md5: 0b0154421989637d424ccf0f104be51a depends: - - __glibc >=2.17,<3.0.a0 - - keyutils >=1.6.3,<2.0a0 - - libedit >=3.1.20250104,<3.2.0a0 - - libedit >=3.1.20250104,<4.0a0 - - libgcc >=14 - - libstdcxx >=14 - - openssl >=3.5.5,<4.0a0 + - arrow >=0.15.0 + - python >=3.9 license: MIT license_family: MIT - purls: [] - size: 1386730 - timestamp: 1769769569681 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed - md5: e446e1822f4da8e5080a9de93474184d + purls: + - pkg:pypi/isoduration?source=hash-mapping + size: 19832 + timestamp: 1733493720346 +- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 + md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 depends: - - __osx >=11.0 - - libcxx >=19 - - libedit >=3.1.20250104,<3.2.0a0 - - libedit >=3.1.20250104,<4.0a0 - - openssl >=3.5.5,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 1160828 - timestamp: 1769770119811 -- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda - sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761 - md5: 4432f52dc0c8eb6a7a6abc00a037d93c - depends: - - openssl >=3.5.5,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 751055 - timestamp: 1769769688841 -- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda - sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 - md5: 9b965c999135d43a3d0f7bd7d024e26a + - parso >=0.8.3,<0.9.0 + - python >=3.9 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/jedi?source=hash-mapping + size: 843646 + timestamp: 1733300981994 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b + md5: 04558c96691bed63104678757beb4f8d depends: + - markupsafe >=2.0 - python >=3.10 - license: MIT - license_family: MIT + - python + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/lark?source=hash-mapping - size: 94312 - timestamp: 1761596921009 -- pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl - name: lazy-loader - version: '0.5' - sha256: ab0ea149e9c554d4ffeeb21105ac60bed7f3b4fd69b1d2360a4add51b170b005 - requires_dist: - - packaging - - pytest>=8.0 ; extra == 'test' - - pytest-cov>=5.0 ; extra == 'test' - - coverage[toml]>=7.2 ; extra == 'test' - - pre-commit==4.3.0 ; extra == 'lint' - - changelist==0.5 ; extra == 'dev' - - spin==0.15 ; extra == 'dev' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c - md5: 18335a698559cdbcd86150a48bf54ba6 - depends: - - __glibc >=2.17,<3.0.a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - binutils_impl_linux-64 2.45.1 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 728002 - timestamp: 1774197446916 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda - sha256: a7a4481a4d217a3eadea0ec489826a69070fcc3153f00443aa491ed21527d239 - md5: 6f7b4302263347698fd24565fbf11310 + - pkg:pypi/jinja2?source=compressed-mapping + size: 120685 + timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-ansible-filters-1.3.2-pyhd8ed1ab_1.conda + sha256: a36789229ca9ce5315265b9d425abce9acb4691f5864aea69e935020545a9acb + md5: 974c5b3e353f031cfcf2365c9d375926 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - constrains: - - libabseil-static =20260107.1=cxx17* - - abseil-cpp =20260107.1 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 1384817 - timestamp: 1770863194876 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda - sha256: 756611fbb8d2957a5b4635d9772bd8432cb6ddac05580a6284cca6fdc9b07fca - md5: bb65152e0d7c7178c0f1ee25692c9fd1 + - jinja2 + - python >=3.9 + - pyyaml + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/jinja2-ansible-filters?source=hash-mapping + size: 20315 + timestamp: 1734906203051 +- conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda + sha256: 9daa95bd164c8fa23b3ab196e906ef806141d749eddce2a08baa064f722d25fa + md5: 1269891272187518a0a75c286f7d0bbf depends: - - __osx >=11.0 - - libcxx >=19 - constrains: - - abseil-cpp =20260107.1 - - libabseil-static =20260107.1=cxx17* + - python >=3.10 license: Apache-2.0 - license_family: Apache - purls: [] - size: 1229639 - timestamp: 1770863511331 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e - md5: 72c8fd1af66bd67bf580645b426513ed - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 79965 - timestamp: 1764017188531 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 - md5: 006e7ddd8a110771134fcc4e1e3a6ffa - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 79443 - timestamp: 1764017945924 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b - md5: 366b40a69f0ad6072561c1d09301c886 + license_family: APACHE + purls: + - pkg:pypi/json5?source=compressed-mapping + size: 34731 + timestamp: 1774655440045 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda + sha256: a3d10301b6ff399ba1f3d39e443664804a3d28315a4fb81e745b6817845f70ae + md5: 89bf346df77603055d3c8fe5811691e6 depends: - - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.2.0 hb03c661_1 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 34632 - timestamp: 1764017199083 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf - md5: 079e88933963f3f149054eec2c487bc2 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jsonpointer?source=hash-mapping + size: 14190 + timestamp: 1774311356147 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 + md5: ada41c863af263cc4c5fcbaff7c3e4dc depends: - - __osx >=11.0 - - libbrotlicommon 1.2.0 hc919400_1 + - attrs >=22.2.0 + - jsonschema-specifications >=2023.3.6 + - python >=3.10 + - referencing >=0.28.4 + - rpds-py >=0.25.0 + - python license: MIT license_family: MIT - purls: [] - size: 29452 - timestamp: 1764017979099 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d - md5: 4ffbb341c8b616aa2494b6afb26a0c5f + purls: + - pkg:pypi/jsonschema?source=hash-mapping + size: 82356 + timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 + md5: 439cd0f567d697b20a8f45cb70a1005a depends: - - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.2.0 hb03c661_1 - - libgcc >=14 + - python >=3.10 + - referencing >=0.31.0 + - python license: MIT license_family: MIT - purls: [] - size: 298378 - timestamp: 1764017210931 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 - md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 + purls: + - pkg:pypi/jsonschema-specifications?source=hash-mapping + size: 19236 + timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda + sha256: 6886fc61e4e4edd38fd38729976b134e8bd2143f7fce56cc80d7ac7bac99bce1 + md5: 8368d58342d0825f0843dc6acdd0c483 depends: - - __osx >=11.0 - - libbrotlicommon 1.2.0 hc919400_1 + - jsonschema >=4.26.0,<4.26.1.0a0 + - fqdn + - idna + - isoduration + - jsonpointer >1.13 + - rfc3339-validator + - rfc3986-validator >0.1.0 + - rfc3987-syntax >=1.1.0 + - uri-template + - webcolors >=24.6.0 license: MIT license_family: MIT purls: [] - size: 290754 - timestamp: 1764018009077 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda - sha256: 76c3d3c702593b6ef57dc2f99c082193a99835526634b844f4a78ae3aecdb6c8 - md5: d0a2e921c5a89df73118cff1afed5213 - depends: - - __osx >=11.0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 570968 - timestamp: 1778110367423 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 - md5: c277e0a4d549b03ac1e9d6cbbe3d017b + size: 4740 + timestamp: 1767839954258 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda + sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e + md5: 0c3b465ceee138b9c39279cc02e5c4a0 depends: - - ncurses - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause + - importlib-metadata >=4.8.3 + - jupyter_server >=1.1.2 + - python >=3.10 + - python + license: BSD-3-Clause license_family: BSD - purls: [] - size: 134676 - timestamp: 1738479519902 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 - md5: 44083d2d2c2025afca315c7a172eab2b + purls: + - pkg:pypi/jupyter-lsp?source=compressed-mapping + size: 61633 + timestamp: 1775136333147 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + sha256: e402bd119720862a33229624ec23645916a7d47f30e1711a4af9e005162b84f3 + md5: 8a3d6d0523f66cf004e563a50d9392b3 depends: - - ncurses - - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause + - jupyter_core >=5.1 + - python >=3.10 + - python-dateutil >=2.8.2 + - pyzmq >=25.0 + - tornado >=6.4.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause license_family: BSD - purls: [] - size: 107691 - timestamp: 1738479560845 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 - md5: 172bf1cd1ff8629f2b1179945ed45055 + purls: + - pkg:pypi/jupyter-client?source=hash-mapping + size: 112785 + timestamp: 1767954655912 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc + md5: a8db462b01221e9f5135be466faeb3e0 depends: - - libgcc-ng >=12 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 112766 - timestamp: 1702146165126 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f - md5: 36d33e440c31857372a72137f78bacf5 - license: BSD-2-Clause + - __win + - pywin32 + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause license_family: BSD - purls: [] - size: 107458 - timestamp: 1702146414478 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda - sha256: ea33c40977ea7a2c3658c522230058395bc2ee0d89d99f0711390b6a1ee80d12 - md5: a3b390520c563d78cc58974de95a03e5 + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 64679 + timestamp: 1760643889625 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a + md5: b38fe4e78ee75def7e599843ef4c1ab0 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - __unix + - python + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python constrains: - - expat 2.8.0.* - license: MIT - license_family: MIT - purls: [] - size: 77241 - timestamp: 1777846112704 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda - sha256: f4b1cafc59afaede8fa0a2d9cf376840f1c553001acd72f6ead18bbc8ac8c49c - md5: 65466e82c09e888ca7560c11a97d5450 + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 65503 + timestamp: 1760643864586 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda + sha256: c7edb5682c6316a95ad781dccb1b6589cd2ec0bf94f23c21152974eb0363b5d7 + md5: bf42ee94c750c0b2e7e998b79ac299ea depends: - - __osx >=11.0 - constrains: - - expat 2.8.0.* - license: MIT - license_family: MIT - purls: [] - size: 68789 - timestamp: 1777846180142 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda - sha256: 2d81d647c1f01108803457cac999b947456f44dd0a3c2325395677feacaeca67 - md5: 264e350e035092b5135a2147c238aec4 + - jsonschema-with-format-nongpl >=4.18.0 + - packaging + - python >=3.10 + - python-json-logger >=2.0.4 + - pyyaml >=5.3 + - referencing + - rfc3339-validator + - rfc3986-validator >=0.1.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-events?source=compressed-mapping + size: 24002 + timestamp: 1776861872237 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + sha256: 04fb8ea7749f67abaf76df6257bf86688e1389ceed55eb4fb0176fd2e882dbd6 + md5: 5ee7945accf0f215ddd6055d25d7cd83 depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 + - anyio >=3.1.0 + - argon2-cffi >=21.1 + - jinja2 >=3.0.3 + - jupyter_client >=7.4.4 + - jupyter_core >=4.12,!=5.0.* + - jupyter_events >=0.11.0 + - jupyter_server_terminals >=0.4.4 + - nbconvert-core >=6.4.4 + - nbformat >=5.3.0 + - overrides >=5.0 + - packaging >=22.0 + - prometheus_client >=0.9 + - python >=3.10 + - pyzmq >=24 + - send2trash >=1.8.2 + - terminado >=0.8.3 + - tornado >=6.2.0 + - traitlets >=5.6.0 + - websocket-client >=1.7 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/jupyter-server?source=compressed-mapping + size: 360522 + timestamp: 1778060967727 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda + sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 + md5: 7b8bace4943e0dc345fc45938826f2b8 + depends: + - python >=3.10 + - terminado >=0.8.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-server-terminals?source=hash-mapping + size: 22052 + timestamp: 1768574057200 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + sha256: b85befad5ba1f50c0cc042a2ffb26441d13ffc2f18572dc20d3541476da0c7b9 + md5: 2ffe77234070324e763a6eddabb5f467 + depends: + - async-lru >=1.0.0 + - httpx >=0.25.0,<1 + - ipykernel >=6.5.0,!=6.30.0 + - jinja2 >=3.0.3 + - jupyter-lsp >=2.0.0 + - jupyter_core + - jupyter_server >=2.4.0,<3 + - jupyterlab_server >=2.28.0,<3 + - notebook-shim >=0.2 + - packaging + - python >=3.10 + - setuptools >=41.1.0 + - tomli >=1.2.2 + - tornado >=6.2.0 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab?source=compressed-mapping + size: 8861204 + timestamp: 1777483115382 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda + sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 + md5: fd312693df06da3578383232528c468d + depends: + - pygments >=2.4.1,<3 + - python >=3.9 constrains: - - expat 2.8.0.* - license: MIT - license_family: MIT - purls: [] - size: 71094 - timestamp: 1777846223617 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 - md5: a360c33a5abe61c07959e449fa1453eb + - jupyterlab >=4.0.8,<5.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-pygments?source=hash-mapping + size: 18711 + timestamp: 1733328194037 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda + sha256: 381d2d6a259a3be5f38a69463e0f6c5dcf1844ae113058007b51c3bef13a7cee + md5: a63877cb23de826b1620d3adfccc4014 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 58592 - timestamp: 1769456073053 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 - md5: 43c04d9cb46ef176bb2a4c77e324d599 + - babel >=2.10 + - jinja2 >=3.0.3 + - json5 >=0.9.0 + - jsonschema >=4.18 + - jupyter_server >=1.21,<3 + - packaging >=21.3 + - python >=3.10 + - requests >=2.31 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyterlab-server?source=hash-mapping + size: 51621 + timestamp: 1761145478692 +- conda: https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda + sha256: 49570840fb15f5df5d4b4464db8ee43a6d643031a2bc70ef52120a52e3809699 + md5: 9b965c999135d43a3d0f7bd7d024e26a depends: - - __osx >=11.0 + - python >=3.10 license: MIT license_family: MIT - purls: [] - size: 40979 - timestamp: 1769456747661 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 - md5: 720b39f5ec0610457b725eb3f396219a + purls: + - pkg:pypi/lark?source=hash-mapping + size: 94312 + timestamp: 1761596921009 +- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 + md5: 00e120ce3e40bad7bfc78861ce3c4a25 depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 45831 - timestamp: 1769456418774 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 - md5: 0aa00f03f9e39fb9876085dee11a85d4 + - python >=3.10 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/matplotlib-inline?source=hash-mapping + size: 15175 + timestamp: 1761214578417 +- conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda + sha256: b52dc6c78fbbe7a3008535cb8bfd87d70d8053e9250bbe16e387470a9df07070 + md5: b97e84d1553b4a1c765b87fff83453ad depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - constrains: - - libgcc-ng ==15.2.0=*_18 - - libgomp 15.2.0 he0feb66_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 1041788 - timestamp: 1771378212382 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 - md5: d5e96b1ed75ca01906b3d2469b4ce493 - depends: - - libgcc 15.2.0 he0feb66_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 27526 - timestamp: 1771378224552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 - md5: 239c5e9546c38a1e884d69effcf4c882 - depends: - - __glibc >=2.17,<3.0.a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 603262 - timestamp: 1771378117851 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d - md5: b88d90cad08e6bc8ad540cb310a761fb + - python >=3.10 + - typing_extensions + - python + license: BSD-3-Clause + purls: + - pkg:pypi/mistune?source=compressed-mapping + size: 74567 + timestamp: 1777824616382 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + sha256: 1b66960ee06874ddceeebe375d5f17fb5f393d025a09e15b830ad0c4fffb585b + md5: 00f5b8dafa842e0c27c1cd7296aa4875 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - xz 5.8.3.* - license: 0BSD - purls: [] - size: 113478 - timestamp: 1775825492909 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - sha256: 34878d87275c298f1a732c6806349125cebbf340d24c6c23727268184bba051e - md5: b1fd823b5ae54fbec272cea0811bd8a9 + - jupyter_client >=6.1.12 + - jupyter_core >=4.12,!=5.0.* + - nbformat >=5.1 + - python >=3.8 + - traitlets >=5.4 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbclient?source=compressed-mapping + size: 28473 + timestamp: 1766485646962 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda + sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 + md5: 2bce0d047658a91b99441390b9b27045 depends: - - __osx >=11.0 + - beautifulsoup4 + - bleach-with-css !=5.0.0 + - defusedxml + - importlib-metadata >=3.6 + - jinja2 >=3.0 + - jupyter_core >=4.7 + - jupyterlab_pygments + - markupsafe >=2.0 + - mistune >=2.0.3,<4 + - nbclient >=0.5.0 + - nbformat >=5.7 + - packaging + - pandocfilters >=1.4.1 + - pygments >=2.4.1 + - python >=3.10 + - traitlets >=5.1 + - python constrains: - - xz 5.8.3.* - license: 0BSD - purls: [] - size: 92472 - timestamp: 1775825802659 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda - sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 - md5: 8f83619ab1588b98dd99c90b0bfc5c6d + - pandoc >=2.9.2,<4.0.0 + - nbconvert ==7.17.1 *_0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbconvert?source=compressed-mapping + size: 202229 + timestamp: 1775615493260 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda + sha256: 7a5bd30a2e7ddd7b85031a5e2e14f290898098dc85bea5b3a5bf147c25122838 + md5: bbe1963f1e47f594070ffe87cdf612ea depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - xz 5.8.3.* - license: 0BSD - purls: [] - size: 106486 - timestamp: 1775825663227 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 - md5: 2c21e66f50753a083cbe6b80f38268fa + - jsonschema >=2.6 + - jupyter_core >=4.12,!=5.0.* + - python >=3.9 + - python-fastjsonschema >=2.15 + - traitlets >=5.1 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nbformat?source=hash-mapping + size: 100945 + timestamp: 1733402844974 +- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 + md5: 598fd7d4d0de2455fb74f56063969a97 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - python >=3.9 license: BSD-2-Clause license_family: BSD - purls: [] - size: 92400 - timestamp: 1769482286018 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 - md5: 57c4be259f5e0b99a5983799a228ae55 + purls: + - pkg:pypi/nest-asyncio?source=hash-mapping + size: 11543 + timestamp: 1733325673691 +- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda + sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 + md5: e7f89ea5f7ea9401642758ff50a2d9c1 depends: - - __osx >=11.0 - license: BSD-2-Clause + - jupyter_server >=1.8,<3 + - python >=3.9 + license: BSD-3-Clause license_family: BSD - purls: [] - size: 73690 - timestamp: 1769482560514 -- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda - sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 - md5: e4a9fc2bba3b022dad998c78856afe47 + purls: + - pkg:pypi/notebook-shim?source=hash-mapping + size: 16817 + timestamp: 1733408419340 +- conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda + sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c + md5: e51f1e4089cad105b6cac64bd8166587 depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause + - python >=3.9 + - typing_utils + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/overrides?source=hash-mapping + size: 30139 + timestamp: 1734587755455 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda + sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 + md5: 4c06a92e74452cfa53623a81592e8934 + depends: + - python >=3.8 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/packaging?source=compressed-mapping + size: 91574 + timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 + sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f + md5: 457c2c8c08e54905d6954e79cb5b5db9 + depends: + - python !=3.0,!=3.1,!=3.2,!=3.3 + license: BSD-3-Clause license_family: BSD - purls: [] - size: 89411 - timestamp: 1769482314283 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda - sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f - md5: 2a45e7f8af083626f009645a6481f12d + purls: + - pkg:pypi/pandocfilters?source=hash-mapping + size: 11627 + timestamp: 1631603397334 +- conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda + sha256: ce76d5a1fc6c7ef636cbdbf14ce2d601a1bfa0dd8d286507c1fd02546fccb94b + md5: 1a884d2b1ea21abfb73911dcdb8342e4 depends: - - __glibc >=2.17,<3.0.a0 - - c-ares >=1.34.6,<2.0a0 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libgcc >=14 - - libstdcxx >=14 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.5,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 663344 - timestamp: 1773854035739 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda - sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a - md5: 6ea18834adbc3b33df9bd9fb45eaf95b + - bcrypt >=3.2 + - cryptography >=3.3 + - invoke >=2.0 + - pynacl >=1.5 + - python >=3.9 + license: LGPL-2.1-or-later + license_family: LGPL + purls: + - pkg:pypi/paramiko?source=hash-mapping + size: 159896 + timestamp: 1755102147074 +- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda + sha256: 611882f7944b467281c46644ffde6c5145d1a7730388bcde26e7e86819b0998e + md5: 39894c952938276405a1bd30e4ce2caf depends: - - __osx >=11.0 - - c-ares >=1.34.6,<2.0a0 - - libcxx >=19 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.5,<4.0a0 + - python >=3.10 + - python license: MIT license_family: MIT - purls: [] - size: 576526 - timestamp: 1773854624224 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 - md5: d864d34357c3b65a4b731f78c0801dc4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-only - license_family: GPL - purls: [] - size: 33731 - timestamp: 1750274110928 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda - sha256: 64e5c80cbce4680a2d25179949739a6def695d72c40ca28f010711764e372d97 - md5: 7af961ef4aa2c1136e11dd43ded245ab + purls: + - pkg:pypi/parso?source=compressed-mapping + size: 82472 + timestamp: 1777722955579 +- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + sha256: 6eaee417d33f298db79bc7185ab1208604c0e6cf51dade34cd513c6f9db9c6f3 + md5: 11adc78451c998c0fd162584abfa3559 depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: ISC - purls: [] - size: 277661 - timestamp: 1772479381288 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda - sha256: df603472ea1ebd8e7d4fb71e4360fe48d10b11c240df51c129de1da2ff9e8227 - md5: 7cc5247987e6d115134ebab15186bc13 + - python >=3.10 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/pathspec?source=compressed-mapping + size: 56559 + timestamp: 1777271601895 +- conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a + md5: d0d408b1f18883a944376da5cf8101ea depends: - - __osx >=11.0 + - ptyprocess >=0.5 + - python >=3.9 license: ISC - purls: [] - size: 248039 - timestamp: 1772479570912 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda - sha256: d915f4fa8ebbf237c7a6e511ed458f2cfdc7c76843a924740318a15d0dd33d6d - md5: da2aa614d16a795b3007b6f4a1318a81 + purls: + - pkg:pypi/pexpect?source=hash-mapping + size: 53561 + timestamp: 1733302019362 +- conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda + sha256: 506c9330b8dc5ae98f4c32629fa59fa40e6bdd42a681c48d2f9554693dd01156 + md5: d57ef7cb7ad6b5d62cef8b9bdf1d400b depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: ISC - purls: [] - size: 276860 - timestamp: 1772479407566 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d - md5: 7dc38adcbf71e6b38748e919e16e0dce + - ipykernel >=6 + - jupyter_client >=7 + - jupyter_server >=2.4 + - msgspec >=0.18 + - python >=3.10 + - returns >=0.23 + - tomli >=2 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pixi-kernel?source=hash-mapping + size: 39509 + timestamp: 1764156429044 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + sha256: 8f29915c172f1f7f4f7c9391cd5dac3ebf5d13745c8b7c8006032615246345a5 + md5: 89c0b6d1793601a2a3a3f7d2d3d8b937 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libzlib >=1.3.2,<2.0a0 - license: blessing - purls: [] - size: 954962 - timestamp: 1777986471789 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda - sha256: 49daec7c83e70d4efc17b813547824bc2bcf2f7256d84061d24fbfe537da9f74 - md5: 6681822ea9d362953206352371b6a904 + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/platformdirs?source=compressed-mapping + size: 25862 + timestamp: 1775741140609 +- conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda + sha256: 972e0c1c9f0b1763d482e885732baef7f9a0cbe8686f5e2c6bdd88838619a59a + md5: 7fd2e38f4e608f5ebd80f871352c5495 depends: - - __osx >=11.0 - - libzlib >=1.3.2,<2.0a0 - license: blessing - purls: [] - size: 920047 - timestamp: 1777987051643 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda - sha256: e70562450332ca8954bc16f3455468cca5ef3695c7d7187ecc87f8fc3c70e9eb - md5: 7fea434a17c323256acc510a041b80d7 + - python >=3.10 + - pywin32-on-windows + - paramiko + - importlib_resources + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/plumbum?source=hash-mapping + size: 103911 + timestamp: 1761911487086 +- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda + sha256: 4d7ec90d4f9c1f3b4a50623fefe4ebba69f651b102b373f7c0e9dbbfa43d495c + md5: a11ab1f31af799dd93c3a39881528884 depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: blessing - purls: [] - size: 1304178 - timestamp: 1777986510497 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e - md5: 1b08cd684f34175e4514474793d44bcb + - python >=3.10 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/prometheus-client?source=compressed-mapping + size: 57113 + timestamp: 1775771465170 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda + sha256: ebc1bb62ac612af6d40667da266ff723662394c0ca78935340a5b5c14831227b + md5: d17ae9db4dc594267181bd199bf9a551 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 he0feb66_18 + - python >=3.9 + - wcwidth constrains: - - libstdcxx-ng ==15.2.0=*_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 5852330 - timestamp: 1771378262446 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda - sha256: bc1b08c92626c91500fd9f26f2c797f3eb153b627d53e9c13cd167f1e12b2829 - md5: 38ffe67b78c9d4de527be8315e5ada2c + - prompt_toolkit 3.0.51 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/prompt-toolkit?source=hash-mapping + size: 271841 + timestamp: 1744724188108 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda + sha256: 936189f0373836c1c77cd2d6e71ba1e583e2d3920bf6d015e96ee2d729b5e543 + md5: 1e61ab85dd7c60e5e73d853ea035dc29 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - prompt-toolkit >=3.0.51,<3.0.52.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 40297 - timestamp: 1775052476770 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b - md5: 0f03292cc56bf91a077a134ea8747118 + size: 7182 + timestamp: 1744724189376 +- conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + sha256: a7713dfe30faf17508ec359e0bc7e0983f5d94682492469bd462cdaae9c64d83 + md5: 7d9daffbb8d8e0af0f769dbbcd173a54 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - python >=3.9 + license: ISC + purls: + - pkg:pypi/ptyprocess?source=hash-mapping + size: 19457 + timestamp: 1733302371990 +- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 + md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 + depends: + - python >=3.9 license: MIT license_family: MIT - purls: [] - size: 895108 - timestamp: 1753948278280 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 - md5: c0d87c3c8e075daf1daf6c31b53e8083 + purls: + - pkg:pypi/pure-eval?source=hash-mapping + size: 16668 + timestamp: 1733569518868 +- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 + md5: 12c566707c80111f9799308d9e265aef depends: - - __osx >=11.0 + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pycparser?source=hash-mapping + size: 110100 + timestamp: 1733195786147 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda + sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f + md5: 729843edafc0899b3348bd3f19525b9d + depends: + - typing-inspection >=0.4.2 + - typing_extensions >=4.14.1 + - python >=3.10 + - annotated-types >=0.6.0 + - pydantic-core ==2.46.4 + - python license: MIT license_family: MIT - purls: [] - size: 421195 - timestamp: 1753948426421 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c - md5: 5aa797f8787fe7a17d1b0821485b5adc + purls: + - pkg:pypi/pydantic?source=compressed-mapping + size: 346511 + timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda + sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 + md5: 16c18772b340887160c79a6acc022db0 depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - purls: [] - size: 100393 - timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 - md5: d87ff7921124eccd67248aa483c23fec + - python >=3.10 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/pygments?source=compressed-mapping + size: 893031 + timestamp: 1774796815820 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca + md5: e2fd202833c4a981ce8a65974fe4abd1 depends: - - __glibc >=2.17,<3.0.a0 - constrains: - - zlib 1.3.2 *_2 - license: Zlib - license_family: Other + - __win + - python >=3.9 + - win_inet_pton + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21784 + timestamp: 1733217448189 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 + md5: 461219d1a5bd61342293efa2c0c90eac + depends: + - __unix + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21085 + timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 + md5: 5b8d21249ff20967101ffa321cab24e8 + depends: + - python >=3.9 + - six >=1.5 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/python-dateutil?source=hash-mapping + size: 233310 + timestamp: 1751104122689 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda + sha256: df9aa74e9e28e8d1309274648aac08ec447a92512c33f61a8de0afa9ce32ebe8 + md5: 23029aae904a2ba587daba708208012f + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fastjsonschema?source=hash-mapping + size: 244628 + timestamp: 1755304154927 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda + sha256: b2e51d83e5ebeb7e9fde1cde822a60e8564cc9dabd786ad853056afbf708a466 + md5: fd00e4b24ea88093c93f5c9bad27b52f + depends: + - cpython 3.13.13.* + - python_abi * *_cp313 + license: Python-2.0 purls: [] - size: 63629 - timestamp: 1774072609062 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 - md5: bc5a5721b6439f2f62a84f2548136082 + size: 48536 + timestamp: 1775613791711 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + sha256: 1c55116c22512cef7b01d55ae49697707f2c1fd829407183c19817e2d300fd8d + md5: 1cd2f3e885162ee1366312bd1b1677fd depends: - - __osx >=11.0 + - python >=3.10 + - typing_extensions + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/python-json-logger?source=compressed-mapping + size: 18969 + timestamp: 1777318679482 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda + sha256: e943f9c15a6bdba2e1b9f423ab913b3f6b02197b0ef9f8e6b7464d78b59965b9 + md5: f6ad7450fc21e00ecc23812baed6d2e4 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tzdata?source=compressed-mapping + size: 146639 + timestamp: 1777068997932 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda + build_number: 8 + sha256: fddf123692aa4b1fc48f0471e346400d9852d96eeed77dbfdd746fa50a8ff894 + md5: 8fcb6b0e2161850556231336dae58358 constrains: - - zlib 1.3.2 *_2 - license: Zlib - license_family: Other + - python 3.11.* *_cpython + license: BSD-3-Clause + license_family: BSD purls: [] - size: 47759 - timestamp: 1774072956767 -- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda - sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 - md5: dbabbd6234dea34040e631f87676292f - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 + size: 7003 + timestamp: 1752805919375 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + build_number: 8 + sha256: 210bffe7b121e651419cb196a2a63687b087497595c9be9d20ebe97dd06060a7 + md5: 94305520c52a4aa3f6c2b1ff6008d9f8 constrains: - - zlib 1.3.2 *_2 - license: Zlib - license_family: Other + - python 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 58347 - timestamp: 1774072851498 -- pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: llvmlite - version: 0.47.0 - sha256: 2699a74321189e812d476a43d6d7f652f51811e7b5aad9d9bba842a1c7927acb - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/34/0b/b9d1911cfefa61399821dfb37f486d83e0f42630a8d12f7194270c417002/llvmlite-0.47.0-cp311-cp311-macosx_11_0_arm64.whl - name: llvmlite - version: 0.47.0 - sha256: 74090f0dcfd6f24ebbef3f21f11e38111c4d7e6919b54c4416e1e357c3446b07 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: llvmlite - version: 0.47.0 - sha256: ca14f02e29134e837982497959a8e2193d6035235de1cb41a9cb2bd6da4eedbb - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl - name: llvmlite - version: 0.47.0 - sha256: c2e9adf8698d813a9a5efb2d4370caf344dbc1e145019851fee6a6f319ba760e - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl - name: llvmlite - version: 0.47.0 - sha256: a3c6a735d4e1041808434f9d440faa3d78d9b4af2ee64d05a66f351883b6ceec - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl - name: llvmlite - version: 0.47.0 - sha256: c37d6eb7aaabfa83ab9c2ff5b5cdb95a5e6830403937b2c588b7490724e05327 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - name: lmfit - version: 1.3.4 - sha256: afce1593b42324d37ae2908249b0c55445e2f4c1a0474ff706a8e2f7b5d949fa - requires_dist: - - asteval>=1.0 - - numpy>=1.24 - - scipy>=1.10.0 - - uncertainties>=3.2.2 - - dill>=0.3.4 - - build ; extra == 'dev' - - check-wheel-contents ; extra == 'dev' - - flake8-pyproject ; extra == 'dev' - - pre-commit ; extra == 'dev' - - twine ; extra == 'dev' - - cairosvg ; extra == 'doc' - - corner ; extra == 'doc' - - emcee>=3.0.0 ; extra == 'doc' - - ipykernel ; extra == 'doc' - - jupyter-sphinx>=0.2.4 ; extra == 'doc' - - matplotlib ; extra == 'doc' - - numdifftools ; extra == 'doc' - - pandas ; extra == 'doc' - - pillow ; extra == 'doc' - - pycairo ; sys_platform == 'win32' and extra == 'doc' - - sphinx ; extra == 'doc' - - sphinx-gallery>=0.10 ; extra == 'doc' - - sphinxcontrib-svg2pdfconverter ; extra == 'doc' - - sympy ; extra == 'doc' - - coverage ; extra == 'test' - - flaky ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - lmfit[dev,doc,test] ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl - name: locket - version: 1.0.0 - sha256: b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl - name: lxml - version: 6.1.0 - sha256: 183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7 - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl - name: lxml - version: 6.1.0 - sha256: a0092f2b107b69601adf562a57c956fbb596e05e3e6651cabd3054113b007e45 - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl - name: lxml - version: 6.1.0 - sha256: cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9 - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl - name: lxml - version: 6.1.0 - sha256: 4a1503c56e4e2b38dc76f2f2da7bae69670c0f1933e27cfa34b2fa5876410b16 - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - name: lxml - version: 6.1.0 - sha256: 363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - name: lxml - version: 6.1.0 - sha256: e69aa6805905807186eb00e66c6d97a935c928275182eb02ee40ba00da9623b2 - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl - name: mando - version: 0.7.1 - sha256: 26ef1d70928b6057ee3ca12583d73c63e05c49de8972d620c278a7b206581a8a - requires_dist: - - six - - argparse ; python_full_version < '2.7' - - funcsigs ; python_full_version < '3.3' - - rst2ansi ; extra == 'restructuredtext' -- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - name: markdown - version: 3.10.2 - sha256: e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36 - requires_dist: - - coverage ; extra == 'testing' - - pyyaml ; extra == 'testing' - - mkdocs>=1.6 ; extra == 'docs' - - mkdocs-nature>=0.6 ; extra == 'docs' - - mdx-gh-links>=0.2 ; extra == 'docs' - - mkdocstrings[python]>=0.28.3 ; extra == 'docs' - - mkdocs-gen-files ; extra == 'docs' - - mkdocs-section-index ; extra == 'docs' - - mkdocs-literate-nav ; extra == 'docs' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl - name: markdown-it-py - version: 4.1.0 - sha256: d4939a62a2dd0cd9cb80a191a711ba1d39bac8ed5ef9e9966895b0171c01c46d - requires_dist: - - mdurl~=0.1 - - psutil ; extra == 'benchmarking' - - pytest ; extra == 'benchmarking' - - pytest-benchmark ; extra == 'benchmarking' - - commonmark~=0.9 ; extra == 'compare' - - markdown~=3.4 ; extra == 'compare' - - mistletoe~=1.0 ; extra == 'compare' - - mistune~=3.0 ; extra == 'compare' - - panflute~=2.3 ; extra == 'compare' - - markdown-it-pyrs ; extra == 'compare' - - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins>=0.5.0 ; extra == 'plugins' - - gprof2dot ; extra == 'profiling' - - mdit-py-plugins>=0.5.0 ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pyyaml ; extra == 'rtd' - - sphinx ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-book-theme~=1.0 ; extra == 'rtd' - - jupyter-sphinx ; extra == 'rtd' - - ipykernel ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-timeout ; extra == 'testing' - - requests ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl - name: markdown-it-py - version: 4.2.0 - sha256: 9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a - requires_dist: - - mdurl~=0.1 - - psutil ; extra == 'benchmarking' - - pytest ; extra == 'benchmarking' - - pytest-benchmark ; extra == 'benchmarking' - - commonmark~=0.9 ; extra == 'compare' - - markdown~=3.4 ; extra == 'compare' - - mistletoe~=1.0 ; extra == 'compare' - - mistune~=3.0 ; extra == 'compare' - - panflute~=2.3 ; extra == 'compare' - - markdown-it-pyrs ; extra == 'compare' - - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins>=0.5.0 ; extra == 'plugins' - - gprof2dot ; extra == 'profiling' - - mdit-py-plugins>=0.5.0 ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pyyaml ; extra == 'rtd' - - sphinx ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-book-theme~=1.0 ; extra == 'rtd' - - jupyter-sphinx ; extra == 'rtd' - - ipykernel ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - pytest-timeout ; extra == 'testing' - - requests ; extra == 'testing' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda - sha256: 710e207b2e91308a34bcfe547c60ad86c1fa294827266ba18548c1fe1a9d8333 - md5: f9efdf9b0f3d0cc309d56af6edf2a6b0 + size: 7002 + timestamp: 1752805902938 +- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 + sha256: 09803b75cccc16d8586d2f41ea890658d165f4afc359973fa1c7904a2c140eae + md5: 91733394059b880d9cc0d010c20abda0 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - constrains: - - jinja2 >=3.0.0 + - python >=2.7 + - pywin32 license: BSD-3-Clause license_family: BSD - purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 26756 - timestamp: 1772445078834 -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda - sha256: 72ed7c0216541d65a17b171bf2eec4a3b81e9158d8ed48e59e1ecd3ae302d263 - md5: aeb9b9da79fd0258b3db091d1fefcd71 + purls: [] + size: 5282 + timestamp: 1646866839398 +- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 + sha256: 6502696aaef571913b22a808b15c185bd8ea4aabb952685deb29e6a6765761cb + md5: 2807a0becd1d986fe1ef9b7f8135f215 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - constrains: - - jinja2 >=3.0.0 + - __unix + - python >=2.7 license: BSD-3-Clause license_family: BSD + purls: [] + size: 4856 + timestamp: 1646866525560 +- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda + sha256: 0604c6dff3af5f53e34fceb985395d08287137f220450108a795bcd1959caf14 + md5: 34fa231b5c5927684b03bb296bb94ddc + depends: + - prompt_toolkit >=2.0,<4.0 + - python >=3.10 + license: MIT + license_family: MIT purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 26100 - timestamp: 1772445154165 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda - sha256: d635f2b1d9e19e8e68c5d33150f7e4f62df08ef2ef0e85977f743e81939afc01 - md5: ff068874356bbc7f9bd2d793f809f44b + - pkg:pypi/questionary?source=hash-mapping + size: 31257 + timestamp: 1757356458097 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 + md5: 870293df500ca7e18bedefa5838a22ab depends: - - __osx >=11.0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD + - attrs >=22.2.0 + - python >=3.10 + - rpds-py >=0.7.0 + - typing_extensions >=4.4.0 + - python + license: MIT + license_family: MIT purls: - - pkg:pypi/markupsafe?source=compressed-mapping - size: 26511 - timestamp: 1772445369187 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda - sha256: f62892a42948c61aa0a13d9a36ff811651f0a1102331223594aecf3cc042bece - md5: 0195d558b0c0ab8f4af3089af83067c5 + - pkg:pypi/referencing?source=hash-mapping + size: 51788 + timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda + sha256: 7f2c24dd3bd3c104a1d2c9a10ead5ed6758b0976b74f972cfe9c19884ccc4241 + md5: 9659f587a8ceacc21864260acd02fc67 depends: - - __osx >=11.0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 + - python >=3.10 + - certifi >=2023.5.7 + - charset-normalizer >=2,<4 + - idna >=2.5,<4 + - urllib3 >=1.26,<3 + - python constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD + - chardet >=3.0.2,<8 + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 26009 - timestamp: 1772445537524 -- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda - sha256: 3d37fb1900e31131f84549560e7a4bfea5f39aa3ecd73345fef1f33975cf0baa - md5: f55de41c947bdd2ff9bbeffedf8089f7 + - pkg:pypi/requests?source=compressed-mapping + size: 63728 + timestamp: 1777030058920 +- conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda + sha256: 3b45efeae771f1a20307b36ecdb3a8911a89c05382836b50c62b0a99d8d3dfd8 + md5: da94ff04d97ec5efc42cbe5da3c43a84 depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause + - python >=3.11 + - typing_extensions >=4.0,<5.0 + - python + license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 29362 - timestamp: 1772445178723 -- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda - sha256: 9dc626b6c00bc2dbd2494df689876ff675b93d92636ba5df8e37b99040a1f6bc - md5: 5cc690ddf943700e0ef50a265df31f03 + - pkg:pypi/returns?source=hash-mapping + size: 100559 + timestamp: 1776176903101 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda + sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 + md5: 36de09a8d3e5d5e6f4ee63af49e59706 depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD + - python >=3.9 + - six + license: MIT + license_family: MIT purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 28992 - timestamp: 1772445161959 -- pypi: https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl - name: matplotlib - version: 3.10.9 - sha256: dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl - name: matplotlib - version: 3.10.9 - sha256: b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: matplotlib - version: 3.10.9 - sha256: 8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl - name: matplotlib - version: 3.10.9 - sha256: d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: matplotlib - version: 3.10.9 - sha256: 8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl - name: matplotlib - version: 3.10.9 - sha256: f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 - requires_dist: - - contourpy>=1.0.1 - - cycler>=0.10 - - fonttools>=4.22.0 - - kiwisolver>=1.3.1 - - numpy>=1.23 - - packaging>=20.0 - - pillow>=8 - - pyparsing>=3 - - python-dateutil>=2.7 - - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' - - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' - - setuptools-scm>=7,<10 ; extra == 'dev' - - setuptools>=64 ; extra == 'dev' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 - md5: 00e120ce3e40bad7bfc78861ce3c4a25 + - pkg:pypi/rfc3339-validator?source=hash-mapping + size: 10209 + timestamp: 1733600040800 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 + sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 + md5: 912a71cc01012ee38e6b90ddd561e36f + depends: + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3986-validator?source=hash-mapping + size: 7818 + timestamp: 1598024297745 +- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda + sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 + md5: 7234f99325263a5af6d4cd195035e8f2 + depends: + - python >=3.9 + - lark >=1.2.2 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/rfc3987-syntax?source=hash-mapping + size: 22913 + timestamp: 1752876729969 +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda + sha256: 8fc024bf1a7b99fc833b131ceef4bef8c235ad61ecb95a71a6108be2ccda63e8 + md5: b70e2d44e6aa2beb69ba64206a16e4c6 depends: + - __osx + - pyobjc-framework-cocoa - python >=3.10 - - traitlets + - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/matplotlib-inline?source=hash-mapping - size: 15175 - timestamp: 1761214578417 -- pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - name: mdit-py-plugins - version: 0.5.0 - sha256: 07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f - requires_dist: - - markdown-it-py>=2.0.0,<5.0.0 - - pre-commit ; extra == 'code-style' - - myst-parser ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - name: mdurl - version: 0.1.2 - sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl - name: mergedeep - version: 1.3.4 - sha256: 70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307 - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl - name: mike - version: 2.2.0 - sha256: e1f4981c1152eec7c2490a3401142292cc47d686194188416db2648fdfe1d040 - requires_dist: - - jinja2>=2.7 - - mkdocs~=1.0 - - pyparsing>=3.0 - - pyyaml>=5.1 - - pyyaml-env-tag - - verspec - - importlib-metadata ; python_full_version < '3.10' - - importlib-resources ; python_full_version < '3.10' - - coverage ; extra == 'dev' - - flake8-quotes ; extra == 'dev' - - flake8>=3.0 ; extra == 'dev' - - shtab ; extra == 'dev' - - coverage ; extra == 'test' - - flake8-quotes ; extra == 'test' - - flake8>=3.0 ; extra == 'test' - - shtab ; extra == 'test' -- conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - sha256: b52dc6c78fbbe7a3008535cb8bfd87d70d8053e9250bbe16e387470a9df07070 - md5: b97e84d1553b4a1c765b87fff83453ad + - pkg:pypi/send2trash?source=hash-mapping + size: 22519 + timestamp: 1770937603551 +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda + sha256: 305446a0b018f285351300463653d3d3457687270e20eda37417b12ee386ef76 + md5: 6ac53f3fff2c416d63511843a04646fa depends: + - __win + - pywin32 - python >=3.10 - - typing_extensions - python license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/mistune?source=compressed-mapping - size: 74567 - timestamp: 1777824616382 -- pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl - name: mkdocs - version: 1.6.1 - sha256: db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e - requires_dist: - - click>=7.0 - - colorama>=0.4 ; sys_platform == 'win32' - - ghp-import>=1.0 - - importlib-metadata>=4.4 ; python_full_version < '3.10' - - jinja2>=2.11.1 - - markdown>=3.3.6 - - markupsafe>=2.0.1 - - mergedeep>=1.3.4 - - mkdocs-get-deps>=0.2.0 - - packaging>=20.5 - - pathspec>=0.11.1 - - pyyaml-env-tag>=0.1 - - pyyaml>=5.1 - - watchdog>=2.0 - - babel>=2.9.0 ; extra == 'i18n' - - babel==2.9.0 ; extra == 'min-versions' - - click==7.0 ; extra == 'min-versions' - - colorama==0.4 ; sys_platform == 'win32' and extra == 'min-versions' - - ghp-import==1.0 ; extra == 'min-versions' - - importlib-metadata==4.4 ; python_full_version < '3.10' and extra == 'min-versions' - - jinja2==2.11.1 ; extra == 'min-versions' - - markdown==3.3.6 ; extra == 'min-versions' - - markupsafe==2.0.1 ; extra == 'min-versions' - - mergedeep==1.3.4 ; extra == 'min-versions' - - mkdocs-get-deps==0.2.0 ; extra == 'min-versions' - - packaging==20.5 ; extra == 'min-versions' - - pathspec==0.11.1 ; extra == 'min-versions' - - pyyaml-env-tag==0.1 ; extra == 'min-versions' - - pyyaml==5.1 ; extra == 'min-versions' - - watchdog==2.0 ; extra == 'min-versions' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl - name: mkdocs-autorefs - version: 1.4.4 - sha256: 834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089 - requires_dist: - - markdown>=3.3 - - markupsafe>=2.0.1 - - mkdocs>=1.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl - name: mkdocs-get-deps - version: 0.2.2 - sha256: e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650 - requires_dist: - - importlib-metadata>=4.3 ; python_full_version < '3.10' - - mergedeep>=1.3.4 - - platformdirs>=2.2.0 - - pyyaml>=5.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl - name: mkdocs-jupyter - version: 0.26.3 - sha256: cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82 - requires_dist: - - ipykernel>6.0.0,<8 - - jupytext>1.13.8,<2 - - mkdocs-material>9.0.0 - - mkdocs>=1.4.0,<2 - - nbconvert>=7.2.9,<8 - - pygments>2.12.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl - name: mkdocs-markdownextradata-plugin - version: 0.2.6 - sha256: 34dd40870781784c75809596b2d8d879da783815b075336d541de1f150c94242 - requires_dist: - - mkdocs - - pyyaml - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl - name: mkdocs-material - version: 9.7.6 - sha256: 71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba - requires_dist: - - babel>=2.10 - - backrefs>=5.7.post1 - - colorama>=0.4 - - jinja2>=3.1 - - markdown>=3.2 - - mkdocs-material-extensions>=1.3 - - mkdocs>=1.6,<2 - - paginate>=0.5 - - pygments>=2.16 - - pymdown-extensions>=10.2 - - requests>=2.30 - - mkdocs-git-committers-plugin-2>=1.1 ; extra == 'git' - - mkdocs-git-revision-date-localized-plugin>=1.2.4 ; extra == 'git' - - cairosvg>=2.6 ; extra == 'imaging' - - pillow>=10.2 ; extra == 'imaging' - - mkdocs-minify-plugin>=0.7 ; extra == 'recommended' - - mkdocs-redirects>=1.2 ; extra == 'recommended' - - mkdocs-rss-plugin>=1.6 ; extra == 'recommended' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl - name: mkdocs-material-extensions - version: 1.3.1 - sha256: adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl - name: mkdocs-plugin-inline-svg - version: 0.1.0 - sha256: a5aab2d98a19b24019f8e650f54fc647c2f31e7d0e36fc5cf2d2161acc0ea49a - requires_dist: - - mkdocs - requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl - name: mkdocstrings - version: 1.0.4 - sha256: 63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b - requires_dist: - - jinja2>=3.1 - - markdown>=3.6 - - markupsafe>=1.1 - - mkdocs>=1.6 - - mkdocs-autorefs>=1.4 - - pymdown-extensions>=6.3 - - mkdocstrings-crystal>=0.3.4 ; extra == 'crystal' - - mkdocstrings-python-legacy>=0.2.1 ; extra == 'python-legacy' - - mkdocstrings-python>=1.16.2 ; extra == 'python' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - name: mkdocstrings-python - version: 2.0.3 - sha256: 0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 - requires_dist: - - mkdocstrings>=0.30 - - mkdocs-autorefs>=1.4 - - griffelib>=2.0 - - typing-extensions>=4.0 ; python_full_version < '3.11' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - name: mpld3 - version: 0.5.12 - sha256: bea31799a4041029a906f53f2662bbf1c49903e0c0bc712b412354158ec7cf54 - requires_dist: - - jinja2 - - matplotlib -- pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl - name: mpltoolbox - version: 26.2.0 - sha256: cd2668db4216fc4d7c2ba37974961aa61445f1517527b645b6082930e35ba7f0 - requires_dist: - - matplotlib - - ipympl ; extra == 'test' - - pytest>=8.0 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - name: mpmath - version: 1.3.0 - sha256: a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c - requires_dist: - - pytest>=4.6 ; extra == 'develop' - - pycodestyle ; extra == 'develop' - - pytest-cov ; extra == 'develop' - - codecov ; extra == 'develop' - - wheel ; extra == 'develop' - - sphinx ; extra == 'docs' - - gmpy2>=2.1.0a4 ; platform_python_implementation != 'PyPy' and extra == 'gmpy' - - pytest>=4.6 ; extra == 'tests' -- pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl - name: msgpack - version: 1.1.2 - sha256: d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: msgpack - version: 1.1.2 - sha256: fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - name: msgpack - version: 1.1.2 - sha256: a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl - name: msgpack - version: 1.1.2 - sha256: 283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - name: msgpack - version: 1.1.2 - sha256: 42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: msgpack - version: 1.1.2 - sha256: 454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py311h49ec1c0_0.conda - sha256: 59123ba4af69c1e7ca6b1b8ffcc40f2aff9a635814495bda3f4f555b3b929165 - md5: 0347d2804701019ac005528df9eb502c + - pkg:pypi/send2trash?source=hash-mapping + size: 22864 + timestamp: 1770937641143 +- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda + sha256: 59656f6b2db07229351dfb3a859c35e57cc8e8bcbc86d4e501bff881a6f771f1 + md5: 28eb91468df04f655a57bcfbb35fc5c5 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 + - __linux + - python >=3.10 + - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 217556 - timestamp: 1776337480302 -- conda: https://conda.anaconda.org/conda-forge/linux-64/msgspec-0.21.1-py313h07c4f96_0.conda - sha256: a44d23085117672e4e19629ea3e6c53f516984322513c4bfdd052b1c7c6fc8ad - md5: 15c679f7133347d68058b688f3519cea + - pkg:pypi/send2trash?source=hash-mapping + size: 24108 + timestamp: 1770937597662 +- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda + sha256: 82088a6e4daa33329a30bc26dc19a98c7c1d3f05c0f73ce9845d4eab4924e9e1 + md5: 8e194e7b992f99a5015edbd4ebd38efd depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD + - python >=3.10 + license: MIT + license_family: MIT purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 219767 - timestamp: 1776337423071 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda - sha256: 55ce08c77b6e87fcc5cca61a516e81fdcc1cd0969e0204fce0a32ca84118a148 - md5: 24707aa446fa7babd806397b8c5349a2 + - pkg:pypi/setuptools?source=hash-mapping + size: 639697 + timestamp: 1773074868565 +- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d + md5: 3339e3b65d58accf4ca4fb8748ab16b3 depends: - - __osx >=11.0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD + - python >=3.9 + - python + license: MIT + license_family: MIT purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 207945 - timestamp: 1776338655947 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda - sha256: 63cdc0052bd638f1f3df6de438e69275b7b273b4b77dbd1ac34ce25d98cf973c - md5: 2dd8d3b25e88780abc058559bc7975c6 + - pkg:pypi/six?source=hash-mapping + size: 18455 + timestamp: 1753199211006 +- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda + sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad + md5: 03fe290994c5e4ec17293cfb6bdce520 depends: - - __osx >=11.0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD + - python >=3.10 + license: Apache-2.0 + license_family: Apache purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 214497 - timestamp: 1776338358818 -- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda - sha256: d096ad02a47a61aeeade2ad3639cc300adf950790cca097717040d46ca5bff52 - md5: 6e6fd9a9012358254bebee33eb3d7f71 + - pkg:pypi/sniffio?source=hash-mapping + size: 15698 + timestamp: 1762941572482 +- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda + sha256: 23b71ecf089967d2900126920e7f9ff18cdcef82dbff3e2f54ffa360243a17ac + md5: 18de09b20462742fe093ba39185d9bac depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD + - python >=3.10 + license: MIT + license_family: MIT purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 199272 - timestamp: 1776337711230 -- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda - sha256: 4e70a7b9bee6b9dadd1f038da6fcf1627cc53581d1cc01355b66d638ae55c0e3 - md5: 96575971ffc81497b83bf321f0b9e945 + - pkg:pypi/soupsieve?source=hash-mapping + size: 38187 + timestamp: 1769034509657 +- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 + md5: b1b505328da7a6b246787df4b5a49fbc depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD + - asttokens + - executing + - pure_eval + - python >=3.9 + license: MIT + license_family: MIT purls: - - pkg:pypi/msgspec?source=hash-mapping - size: 201017 - timestamp: 1776337591817 -- pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: multidict - version: 6.7.1 - sha256: 439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl - name: multidict - version: 6.7.1 - sha256: 935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: multidict - version: 6.7.1 - sha256: 9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl - name: multidict - version: 6.7.1 - sha256: 960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl - name: multidict - version: 6.7.1 - sha256: bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl - name: multidict - version: 6.7.1 - sha256: f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl - name: narwhals - version: 2.20.0 - sha256: 16e750ea5507d4ba6e8d03455b5f93a535e0405976561baea235bca5dc9f475d - requires_dist: - - cudf-cu12>=24.10.0 ; extra == 'cudf' - - dask[dataframe]>=2024.8 ; extra == 'dask' - - duckdb>=1.1 ; extra == 'duckdb' - - ibis-framework>=6.0.0 ; extra == 'ibis' - - packaging ; extra == 'ibis' - - pyarrow-hotfix ; extra == 'ibis' - - rich ; extra == 'ibis' - - modin ; extra == 'modin' - - pandas>=1.1.3 ; extra == 'pandas' - - polars>=0.20.4 ; extra == 'polars' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - pyspark>=3.5.0 ; extra == 'pyspark' - - pyspark[connect]>=3.5.0 ; extra == 'pyspark-connect' - - duckdb>=1.1 ; extra == 'sql' - - sqlparse ; extra == 'sql' - - sqlframe>=3.22.0,!=3.39.3 ; extra == 'sqlframe' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - sha256: 1b66960ee06874ddceeebe375d5f17fb5f393d025a09e15b830ad0c4fffb585b - md5: 00f5b8dafa842e0c27c1cd7296aa4875 + - pkg:pypi/stack-data?source=hash-mapping + size: 26988 + timestamp: 1733569565672 +- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda + sha256: b375e8df0d5710717c31e7c8e93c025c37fa3504aea325c7a55509f64e5d4340 + md5: e43ca10d61e55d0a8ec5d8c62474ec9e depends: - - jupyter_client >=6.1.12 - - jupyter_core >=4.12,!=5.0.* - - nbformat >=5.1 - - python >=3.8 - - traitlets >=5.4 - license: BSD-3-Clause + - __win + - pywinpty >=1.1.0 + - python >=3.10 + - tornado >=6.1.0 + - python + license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/nbclient?source=compressed-mapping - size: 28473 - timestamp: 1766485646962 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 - md5: 2bce0d047658a91b99441390b9b27045 + - pkg:pypi/terminado?source=hash-mapping + size: 23665 + timestamp: 1766513806974 +- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda + sha256: 6b6727a13d1ca6a23de5e6686500d0669081a117736a87c8abf444d60c1e40eb + md5: 17b43cee5cc84969529d5d0b0309b2cb depends: - - beautifulsoup4 - - bleach-with-css !=5.0.0 - - defusedxml - - importlib-metadata >=3.6 - - jinja2 >=3.0 - - jupyter_core >=4.7 - - jupyterlab_pygments - - markupsafe >=2.0 - - mistune >=2.0.3,<4 - - nbclient >=0.5.0 - - nbformat >=5.7 - - packaging - - pandocfilters >=1.4.1 - - pygments >=2.4.1 + - __unix + - ptyprocess - python >=3.10 - - traitlets >=5.1 + - tornado >=6.1.0 - python - constrains: - - pandoc >=2.9.2,<4.0.0 - - nbconvert ==7.17.1 *_0 - license: BSD-3-Clause + license: BSD-2-Clause license_family: BSD purls: - - pkg:pypi/nbconvert?source=compressed-mapping - size: 202229 - timestamp: 1775615493260 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - sha256: 7a5bd30a2e7ddd7b85031a5e2e14f290898098dc85bea5b3a5bf147c25122838 - md5: bbe1963f1e47f594070ffe87cdf612ea + - pkg:pypi/terminado?source=hash-mapping + size: 24749 + timestamp: 1766513766867 +- conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda + sha256: cad582d6f978276522f84bd209a5ddac824742fe2d452af6acf900f8650a73a2 + md5: f1acf5fdefa8300de697982bcb1761c9 depends: - - jsonschema >=2.6 - - jupyter_core >=4.12,!=5.0.* - - python >=3.9 - - python-fastjsonschema >=2.15 - - traitlets >=5.1 + - python >=3.5 + - webencodings >=0.4 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/nbformat?source=hash-mapping - size: 100945 - timestamp: 1733402844974 -- pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - name: nbmake - version: 1.5.5 - sha256: c6fbe6e48b60cacac14af40b38bf338a3b88f47f085c54ac5b8639ff0babaf4b - requires_dist: - - ipykernel>=5.4.0 - - nbclient>=0.6.6 - - nbformat>=5.0.4 - - pygments>=2.7.3 - - pytest>=6.1.0 - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl - name: nbqa - version: 1.9.1 - sha256: 95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5 - requires_dist: - - autopep8>=1.5 - - ipython>=7.8.0 - - tokenize-rt>=3.2.0 - - tomli - - black ; extra == 'toolchain' - - blacken-docs ; extra == 'toolchain' - - flake8 ; extra == 'toolchain' - - isort ; extra == 'toolchain' - - jupytext ; extra == 'toolchain' - - mypy ; extra == 'toolchain' - - pylint ; extra == 'toolchain' - - pyupgrade ; extra == 'toolchain' - - ruff ; extra == 'toolchain' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - name: nbstripout - version: 0.9.1 - sha256: ca027ee45742ee77e4f8e9080254f9a707f1161ba11367b82fdf4a29892c759e - requires_dist: - - nbformat - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - name: ncrystal - version: 4.4.2 - sha256: e02fa7d743addc3fbea23287737a88b8d01192450fdca51554d3f9032fe4617c - requires_dist: - - ncrystal-core==4.4.2 - - ncrystal-python==4.4.2 - - spglib>=2.1.0 ; extra == 'composer' - - ase>=3.23.0 ; extra == 'cif' - - gemmi>=0.6.1 ; extra == 'cif' - - spglib>=2.1.0 ; extra == 'cif' - - endf-parserpy>=0.14.3 ; extra == 'endf' - - matplotlib>=3.6.0 ; extra == 'plot' - - ase>=3.23.0 ; extra == 'all' - - endf-parserpy>=0.14.3 ; extra == 'all' - - gemmi>=0.6.1 ; extra == 'all' - - matplotlib>=3.6.0 ; extra == 'all' - - spglib>=2.1.0 ; extra == 'all' - - pyyaml>=6.0.0 ; extra == 'devel' - - ase>=3.23.0 ; extra == 'devel' - - cppcheck ; extra == 'devel' - - endf-parserpy>=0.14.3 ; extra == 'devel' - - gemmi>=0.6.1 ; extra == 'devel' - - matplotlib>=3.6.0 ; extra == 'devel' - - mpmath>=1.3.0 ; extra == 'devel' - - numpy>=1.22 ; extra == 'devel' - - pybind11>=2.11.0 ; extra == 'devel' - - ruff>=0.8.1 ; extra == 'devel' - - simple-build-system>=1.6.0 ; extra == 'devel' - - spglib>=2.1.0 ; extra == 'devel' - - tomli>=2.0.0 ; python_full_version < '3.11' and extra == 'devel' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c7/6b/6c02f55c2ce2f137ccca0986be7dd89bea31d5bee4346b4377fa3b8586df/ncrystal_core-4.4.2-py3-none-win_amd64.whl - name: ncrystal-core - version: 4.4.2 - sha256: 9b28a90b63849e6a3a807a0a59f7c2ee57e4c64f5643b2dcb6a798ac8ccf666a - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl - name: ncrystal-core - version: 4.4.2 - sha256: b7e6101a6850aa18cf441825214381614db444ffcba648de8266fe1c4d1024ce - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: ncrystal-core - version: 4.4.2 - sha256: d0d9c47cd017b7cefc52dde50546d7c151bfdd75d345e42e2b3e74ab5fe83c62 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl - name: ncrystal-python - version: 4.4.2 - sha256: f419318d088fade6bcff1e39e15baf6fe69fcf5306dd681fca1106d1f63a89ce - requires_dist: - - numpy>=1.22 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 - md5: fc21868a1a5aacc937e7a18747acb8a5 + - pkg:pypi/tinycss2?source=hash-mapping + size: 28285 + timestamp: 1729802975370 +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + sha256: 91cafdb64268e43e0e10d30bd1bef5af392e69f00edd34dfaf909f69ab2da6bd + md5: b5325cf06a000c5b14970462ff5e4d58 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: X11 AND BSD-3-Clause - purls: [] - size: 918956 - timestamp: 1777422145199 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d - md5: 343d10ed5b44030a2f67193905aea159 + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/tomli?source=hash-mapping + size: 21561 + timestamp: 1774492402955 +- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + sha256: dfb681579be59c2e790c95f7f49b7529a9b0511d6385ad276e3c8988cbd54d2c + md5: 4bada6a6d908a27262af8ebddf4f7492 depends: - - __osx >=11.0 - license: X11 AND BSD-3-Clause + - python >=3.10 + - python + license: BSD-3-Clause + purls: + - pkg:pypi/traitlets?source=compressed-mapping + size: 115165 + timestamp: 1778074251714 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda + sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c + md5: edd329d7d3a4ab45dcf905899a7a6115 + depends: + - typing_extensions ==4.15.0 pyhcf101f3_0 + license: PSF-2.0 + license_family: PSF purls: [] - size: 805509 - timestamp: 1777423252320 -- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 - md5: 598fd7d4d0de2455fb74f56063969a97 + size: 91383 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda + sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a + md5: 53f5409c5cfd6c5a66417d68e3f0a864 + depends: + - python >=3.10 + - typing_extensions >=4.12.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/typing-inspection?source=compressed-mapping + size: 20935 + timestamp: 1777105465795 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 + md5: 0caa1af407ecff61170c9437a808404d + depends: + - python >=3.10 + - python + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/typing-extensions?source=hash-mapping + size: 51692 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda + sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c + md5: f6d7aa696c67756a650e91e15e88223c depends: - python >=3.9 - license: BSD-2-Clause - license_family: BSD + license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/nest-asyncio?source=hash-mapping - size: 11543 - timestamp: 1733325673691 -- pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - name: networkx - version: 3.6.1 - sha256: d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 - requires_dist: - - asv ; extra == 'benchmarking' - - virtualenv ; extra == 'benchmarking' - - numpy>=1.25 ; extra == 'default' - - scipy>=1.11.2 ; extra == 'default' - - matplotlib>=3.8 ; extra == 'default' - - pandas>=2.0 ; extra == 'default' - - pre-commit>=4.1 ; extra == 'developer' - - mypy>=1.15 ; extra == 'developer' - - sphinx>=8.0 ; extra == 'doc' - - pydata-sphinx-theme>=0.16 ; extra == 'doc' - - sphinx-gallery>=0.18 ; extra == 'doc' - - numpydoc>=1.8.0 ; extra == 'doc' - - pillow>=10 ; extra == 'doc' - - texext>=0.6.7 ; extra == 'doc' - - myst-nb>=1.1 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - osmnx>=2.0.0 ; extra == 'example' - - momepy>=0.7.2 ; extra == 'example' - - contextily>=1.6 ; extra == 'example' - - seaborn>=0.13 ; extra == 'example' - - cairocffi>=1.7 ; extra == 'example' - - igraph>=0.11 ; extra == 'example' - - scikit-learn>=1.5 ; extra == 'example' - - iplotx>=0.9.0 ; extra == 'example' - - lxml>=4.6 ; extra == 'extra' - - pygraphviz>=1.14 ; extra == 'extra' - - pydot>=3.0.1 ; extra == 'extra' - - sympy>=1.10 ; extra == 'extra' - - build>=0.10 ; extra == 'release' - - twine>=4.0 ; extra == 'release' - - wheel>=0.40 ; extra == 'release' - - changelist==0.5 ; extra == 'release' - - pytest>=7.2 ; extra == 'test' - - pytest-cov>=4.0 ; extra == 'test' - - pytest-xdist>=3.0 ; extra == 'test' - - pytest-mpl ; extra == 'test-extras' - - pytest-randomly ; extra == 'test-extras' - requires_python: '>=3.11,!=3.14.1' -- pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - name: nodeenv - version: 1.10.0 - sha256: 5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' -- conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda - sha256: d1a673d1418d9e956b6e4e46c23e72a511c5c1d45dc5519c947457427036d5e2 - md5: baffb1570b3918c784d4490babc52fbf + - pkg:pypi/typing-utils?source=hash-mapping + size: 15183 + timestamp: 1733331395943 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain + purls: [] + size: 119135 + timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda + sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 + md5: e7cb0f5745e4c5035a460248334af7eb depends: - - libgcc >=14 - - libstdcxx >=14 - - __glibc >=2.28,<3.0.a0 - - libnghttp2 >=1.68.1,<2.0a0 - - libuv >=1.51.0,<2.0a0 - - c-ares >=1.34.6,<2.0a0 - - openssl >=3.5.5,<4.0a0 - - libsqlite >=3.52.0,<4.0a0 - - icu >=78.3,<79.0a0 - - libzlib >=1.3.2,<2.0a0 - - libabseil >=20260107.1,<20260108.0a0 - - libabseil * cxx17* - - zstd >=1.5.7,<1.6.0a0 - - libbrotlicommon >=1.2.0,<1.3.0a0 - - libbrotlienc >=1.2.0,<1.3.0a0 - - libbrotlidec >=1.2.0,<1.3.0a0 + - python >=3.9 license: MIT license_family: MIT - purls: [] - size: 18829340 - timestamp: 1774514313036 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda - sha256: 4782b172b3b8a557b60bf5f591821cf100e2092ba7a5494ce047dfa41626de26 - md5: ca8277c52fdface8bb8ebff7cd9a6f56 + purls: + - pkg:pypi/uri-template?source=hash-mapping + size: 23990 + timestamp: 1733323714454 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a + md5: 9272daa869e03efe68833e3dc7a02130 depends: - - libcxx >=19 - - __osx >=11.0 - - icu >=78.3,<79.0a0 - - libbrotlicommon >=1.2.0,<1.3.0a0 - - libbrotlienc >=1.2.0,<1.3.0a0 - - libbrotlidec >=1.2.0,<1.3.0a0 - - libnghttp2 >=1.68.1,<2.0a0 - - libuv >=1.51.0,<2.0a0 - - libsqlite >=3.52.0,<4.0a0 - - libzlib >=1.3.2,<2.0a0 - - openssl >=3.5.5,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - - c-ares >=1.34.6,<2.0a0 - - libabseil >=20260107.1,<20260108.0a0 - - libabseil * cxx17* + - backports.zstd >=1.0.0 + - brotli-python >=1.2.0 + - h2 >=4,<5 + - pysocks >=1.5.6,<2.0,!=1.5.7 + - python >=3.10 license: MIT license_family: MIT - purls: [] - size: 17101803 - timestamp: 1774517834028 -- conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda - sha256: 5e38e51da1aa4bc352db9b4cec1c3e25811de0f4408edaa24e009a64de6dbfdf - md5: e626ee7934e4b7cb21ce6b721cff8677 + purls: + - pkg:pypi/urllib3?source=hash-mapping + size: 103172 + timestamp: 1767817860341 +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + sha256: 1ee2d8384972ecbf8630ce8a3ea9d16858358ad3e8566675295e66996d5352da + md5: eb9538b8e55069434a18547f43b96059 + depends: + - python >=3.10 license: MIT license_family: MIT - purls: [] - size: 31271315 - timestamp: 1774517904472 -- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 - md5: e7f89ea5f7ea9401642758ff50a2d9c1 + purls: + - pkg:pypi/wcwidth?source=compressed-mapping + size: 82917 + timestamp: 1777744489106 +- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda + sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 + md5: 6639b6b0d8b5a284f027a2003669aa65 + depends: + - python >=3.10 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/webcolors?source=hash-mapping + size: 18987 + timestamp: 1761899393153 +- conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda + sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 + md5: 2841eb5bfc75ce15e9a0054b98dcd64d depends: - - jupyter_server >=1.8,<3 - python >=3.9 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/notebook-shim?source=hash-mapping - size: 16817 - timestamp: 1733408419340 -- pypi: https://files.pythonhosted.org/packages/44/0b/0615dbedb98f5b32a35a53290fbdc6e22306968109278d7e58df82d7a9f6/numba-0.65.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: numba - version: 0.65.1 - sha256: f80ed83774b5173abd6581cd8d2165d1d38e13d2e5c8155c0c0b421784745420 - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl - name: numba - version: 0.65.1 - sha256: 1735c15c1134a5108b4d6a5c77fc0947924ea066a738dc09a52008c13df9cad3 - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl - name: numba - version: 0.65.1 - sha256: 7020d74b19cdb8cff16506542fdd510756e28c5e7f3bd0b7f574f0f42272fcd9 - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: numba - version: 0.65.1 - sha256: c09f49117ef255e1f1c6dad0c7a1ed39868243862a73be5706793241a3755f1b - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl - name: numba - version: 0.65.1 - sha256: df40a5028a975b9ea66f6a2a3f7abbdbd541a863070e34ed367aff21141248e4 - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl - name: numba - version: 0.65.1 - sha256: 85be74c0d036842699a30058f82fb88fc5ffdc59f7615cab5792ea92914c9b62 - requires_dist: - - llvmlite>=0.47.0.dev0,<0.48 - - numpy>=1.22 - - numpy>=1.22,<2.5 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl - name: numpy - version: 2.4.4 - sha256: 5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl - name: numpy - version: 2.4.4 - sha256: 86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015 - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl - name: numpy - version: 2.4.4 - sha256: 6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: numpy - version: 2.4.4 - sha256: df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502 - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: numpy - version: 2.4.4 - sha256: c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl - name: numpy - version: 2.4.4 - sha256: 4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb - md5: da1b85b6a87e141f5140bb9924cecab0 + - pkg:pypi/webencodings?source=hash-mapping + size: 15496 + timestamp: 1733236131358 +- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda + sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 + md5: 2f1ed718fcd829c184a6d4f0f2e07409 depends: - - __glibc >=2.17,<3.0.a0 - - ca-certificates - - libgcc >=14 + - python >=3.10 license: Apache-2.0 - license_family: Apache - purls: [] - size: 3167099 - timestamp: 1775587756857 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda - sha256: c91bf510c130a1ea1b6ff023e28bac0ccaef869446acd805e2016f69ebdc49ea - md5: 25dcccd4f80f1638428613e0d7c9b4e1 + license_family: APACHE + purls: + - pkg:pypi/websocket-client?source=hash-mapping + size: 61391 + timestamp: 1759928175142 +- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f + md5: 46e441ba871f524e2b067929da3051c2 + depends: + - __win + - python >=3.9 + license: LicenseRef-Public-Domain + purls: + - pkg:pypi/win-inet-pton?source=hash-mapping + size: 9555 + timestamp: 1733130678956 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda + sha256: 523616c0530d305d2216c2b4a8dfd3872628b60083255b89c5e0d8c42e738cca + md5: e1c36c6121a7c9c76f2f148f1e83b983 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/zipp?source=compressed-mapping + size: 24461 + timestamp: 1776131454755 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py311h9408147_2.conda + sha256: c15fc1aa6184185f1b31670a16b76d59f484d3efa25b467f28d59088cf0085c0 + md5: 501c2a606787bcd55b9ddee776208333 depends: - __osx >=11.0 - - ca-certificates - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3106008 - timestamp: 1775587972483 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda - sha256: feb5815125c60f2be4a411e532db1ed1cd2d7261a6a43c54cb6ae90724e2e154 - md5: 05c7d624cff49dbd8db1ad5ba537a8a3 + - cffi >=1.0.1 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 34403 + timestamp: 1762509963182 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-25.1.0-py313h6535dbc_2.conda + sha256: 05ea6fa7109235cfb4fc24526bae1fe82d88bbb5e697ab3945c313f5f041af5b + md5: e23e087109b2096db4cf9a3985bab329 depends: - - ca-certificates - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 9410183 - timestamp: 1775589779763 -- pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl - name: orsopy - version: 1.2.3 - sha256: 11d3ee9a1185467ba4363b24d6b98b268956ee0fb528aeff7ff106b49f363180 - requires_dist: - - pyyaml>=5.4.1 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - name: oscrypto - version: 1.3.0 - sha256: 2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085 - requires_dist: - - asn1crypto>=1.5.1 -- conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - sha256: 1840bd90d25d4930d60f57b4f38d4e0ae3f5b8db2819638709c36098c6ba770c - md5: e51f1e4089cad105b6cac64bd8166587 + - __osx >=11.0 + - cffi >=1.0.1 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 33947 + timestamp: 1762510144907 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py311h36d4fbb_0.conda + sha256: 2e6399a3663e7e20134a208cd09befc44ce1e9efe94d1d36d8911db04f186270 + md5: 3ee7e8ae532366221658b80baee36dc0 depends: - - python >=3.9 - - typing_utils + - python + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 244743 + timestamp: 1777848723707 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.4.0-py313h7208f8c_0.conda + sha256: 257b234caffc760e48c8d7e642d6d0d8bac4341ca19c7df098421358eff636a1 + md5: 84e922fe79295051f6925d7f8d71c98c + depends: + - python + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 242188 + timestamp: 1777848729476 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py311h71babbd_1.conda + sha256: 79594899d1f2472a6d95c3d489268bb9103ba6bab043d9faca379d989074aeb3 + md5: 00ad8eed3ec75b6ec425526968c72e61 + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/overrides?source=hash-mapping - size: 30139 - timestamp: 1734587755455 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 - md5: 4c06a92e74452cfa53623a81592e8934 + - pkg:pypi/bcrypt?source=hash-mapping + size: 268519 + timestamp: 1762497846273 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bcrypt-5.0.0-py313h2c089d5_1.conda + sha256: c8e3b95ad2665dc16ac37888fb91dd481fa759bad1fbf799451d12d6bfaec600 + md5: 4b14cba28eaf98170c2ddd7e900efa07 depends: - - python >=3.8 - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/packaging?source=compressed-mapping - size: 91574 - timestamp: 1777103621679 -- pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl - name: paginate - version: 0.5.7 - sha256: b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 - requires_dist: - - pytest ; extra == 'dev' - - tox ; extra == 'dev' - - black ; extra == 'lint' -- pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl - name: pandas - version: 3.0.2 - sha256: d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668 - requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' + - pkg:pypi/bcrypt?source=hash-mapping + size: 267465 + timestamp: 1762497730829 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py311hdc60ec4_1.conda + sha256: 617545ec0e97d35ed2ff7852f2581a20c0dda80b366d0c42a43706687f971ba8 + md5: 150cbf381febcf0a5e470a8d066e1bc0 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 359588 + timestamp: 1764018467340 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py313hde1f3bb_1.conda + sha256: 2e21dccccd68bedd483300f9ab87a425645f6776e6e578e10e0dd98c946e1be9 + md5: b03732afa9f4f54634d94eb920dfb308 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 359568 + timestamp: 1764018359470 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 124834 + timestamp: 1771350416561 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py311hd10dc20_1.conda + sha256: 1ffde698463d6e7ed571bdb85cb17bfc1d3a107c026d20047995512dcc2749ec + md5: 4d7f6780e36f18e7601811dddf3bbec5 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 294848 + timestamp: 1761203196617 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py313h224173a_1.conda + sha256: 1fa69651f5e81c25d48ac42064db825ed1a3e53039629db69f86b952f5ce603c + md5: 050374657d1c7a4f2ea443c0d0cbd9a0 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 291376 + timestamp: 1761203583358 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py311hbb43c59_0.conda + sha256: 6e59412439c8b51ee5f05b3c50b05b43991fa544a895226168fab63be9ba28f9 + md5: cbc7fb4eb2049a4a6cd2c452afd2f7bd + depends: + - __osx >=11.0 + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1855763 + timestamp: 1777966249758 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-48.0.0-py313hda5ae78_0.conda + sha256: 2adca86f420558eaaad8b8a7ecffadc4a23f980c02716d0fd5bee3f51879e76b + md5: 730fd8d2542ece52b71bc4fbb80ceb10 + depends: + - __osx >=11.0 + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1854514 + timestamp: 1777966313532 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py311h8948835_0.conda + sha256: 093b015e9abf27fb4d3b4f7e52417d35cd69a99fab8b95ec5c6c3983275c46ba + md5: 150c921424bc9f08c0378f8a6ae58d05 + depends: + - python + - __osx >=11.0 + - libcxx >=19 + - python 3.11.* *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2668163 + timestamp: 1769745020016 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py313h1188861_0.conda + sha256: 372464b345220758769f49e76d125933008abec7048df4077a851adcc79da1e8 + md5: b3a832c19cfa5dfcce7575750ef693ed + depends: + - python + - libcxx >=19 + - python 3.13.* *_cp313 + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2761021 + timestamp: 1769744996428 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5 + md5: f1182c91c0de31a7abd40cedf6a5ebef + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 12361647 + timestamp: 1773822915649 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed + md5: e446e1822f4da8e5080a9de93474184d + depends: + - __osx >=11.0 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1160828 + timestamp: 1769770119811 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + sha256: 756611fbb8d2957a5b4635d9772bd8432cb6ddac05580a6284cca6fdc9b07fca + md5: bb65152e0d7c7178c0f1ee25692c9fd1 + depends: + - __osx >=11.0 + - libcxx >=19 + constrains: + - abseil-cpp =20260107.1 + - libabseil-static =20260107.1=cxx17* + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1229639 + timestamp: 1770863511331 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 + md5: 006e7ddd8a110771134fcc4e1e3a6ffa + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 79443 + timestamp: 1764017945924 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf + md5: 079e88933963f3f149054eec2c487bc2 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 29452 + timestamp: 1764017979099 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 + md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 290754 + timestamp: 1764018009077 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_0.conda + sha256: 76c3d3c702593b6ef57dc2f99c082193a99835526634b844f4a78ae3aecdb6c8 + md5: d0a2e921c5a89df73118cff1afed5213 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 570968 + timestamp: 1778110367423 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda + sha256: f4b1cafc59afaede8fa0a2d9cf376840f1c553001acd72f6ead18bbc8ac8c49c + md5: 65466e82c09e888ca7560c11a97d5450 + depends: + - __osx >=11.0 + constrains: + - expat 2.8.0.* + license: MIT + license_family: MIT + purls: [] + size: 68789 + timestamp: 1777846180142 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + sha256: 34878d87275c298f1a732c6806349125cebbf340d24c6c23727268184bba051e + md5: b1fd823b5ae54fbec272cea0811bd8a9 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 92472 + timestamp: 1775825802659 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 + md5: 57c4be259f5e0b99a5983799a228ae55 + depends: + - __osx >=11.0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 73690 + timestamp: 1769482560514 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a + md5: 6ea18834adbc3b33df9bd9fb45eaf95b + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 576526 + timestamp: 1773854624224 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.21-h1a92334_3.conda + sha256: df603472ea1ebd8e7d4fb71e4360fe48d10b11c240df51c129de1da2ff9e8227 + md5: 7cc5247987e6d115134ebab15186bc13 + depends: + - __osx >=11.0 + license: ISC + purls: [] + size: 248039 + timestamp: 1772479570912 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda + sha256: 49daec7c83e70d4efc17b813547824bc2bcf2f7256d84061d24fbfe537da9f74 + md5: 6681822ea9d362953206352371b6a904 + depends: + - __osx >=11.0 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 920047 + timestamp: 1777987051643 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 421195 + timestamp: 1753948426421 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 + md5: bc5a5721b6439f2f62a84f2548136082 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 47759 + timestamp: 1774072956767 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py311hc290fe0_1.conda + sha256: d635f2b1d9e19e8e68c5d33150f7e4f62df08ef2ef0e85977f743e81939afc01 + md5: ff068874356bbc7f9bd2d793f809f44b + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=compressed-mapping + size: 26511 + timestamp: 1772445369187 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h65a2061_1.conda + sha256: f62892a42948c61aa0a13d9a36ff811651f0a1102331223594aecf3cc042bece + md5: 0195d558b0c0ab8f4af3089af83067c5 + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 26009 + timestamp: 1772445537524 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py311hc949640_0.conda + sha256: 55ce08c77b6e87fcc5cca61a516e81fdcc1cd0969e0204fce0a32ca84118a148 + md5: 24707aa446fa7babd806397b8c5349a2 + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 207945 + timestamp: 1776338655947 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgspec-0.21.1-py313h0997733_0.conda + sha256: 63cdc0052bd638f1f3df6de438e69275b7b273b4b77dbd1ac34ce25d98cf973c + md5: 2dd8d3b25e88780abc058559bc7975c6 + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 214497 + timestamp: 1776338358818 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d + md5: 343d10ed5b44030a2f67193905aea159 + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + purls: [] + size: 805509 + timestamp: 1777423252320 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.8.2-h7039424_0.conda + sha256: 4782b172b3b8a557b60bf5f591821cf100e2092ba7a5494ce047dfa41626de26 + md5: ca8277c52fdface8bb8ebff7cd9a6f56 + depends: + - libcxx >=19 + - __osx >=11.0 + - icu >=78.3,<79.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libuv >=1.51.0,<2.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + - c-ares >=1.34.6,<2.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + license: MIT + license_family: MIT + purls: [] + size: 17101803 + timestamp: 1774517834028 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + sha256: c91bf510c130a1ea1b6ff023e28bac0ccaef869446acd805e2016f69ebdc49ea + md5: 25dcccd4f80f1638428613e0d7c9b4e1 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3106008 + timestamp: 1775587972483 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda + sha256: 2b774e8f4ccaac8783d1908f281e4bb20b7036d6708dc913ee7811b070f5b4b5 + md5: 7cff50265141513c960f00ba586780ea + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 245203 + timestamp: 1769678306347 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda + sha256: 1d2a6039fb71d61134b1d6816202529f2f6286c83b59bc1491fd288f5c08046e + md5: ba2d89e51a855963c767648f44c03871 + depends: + - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 242596 + timestamp: 1769678288893 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda + sha256: 194e8872dcda301703c8f1427e480fee6421e3901803ffc863b68eb886372eaf + md5: 80d6864b30e0697b652a9bd580b2d351 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - __osx >=11.0 + - python 3.11.* *_cpython + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1730463 + timestamp: 1778084304998 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda + sha256: 5bcc20f2c21d8a20d8f2821caf31d8c0ef2fa3bcdaf7a9bdce62e37be819f1d7 + md5: 32bb0d4dbb1be2064c06248a1190aa96 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - python 3.13.* *_cp313 + - __osx >=11.0 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1720475 + timestamp: 1778084300413 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda + sha256: 503b3a2543577f2fb70ddc44113a4da7ecdfdfb2bf51ecd1203adcb93e7257df + md5: 64d4dd58b1eb87d7e6ba084c7dc9259b + depends: + - __osx >=11.0 + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1188895 + timestamp: 1772171487639 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda + sha256: ef6ab85953ebf81b3b0c6d0b6377eb1a318b07823e76d2c8e850365e60d9ca5c + md5: fca94b9ddea6d5c63ccb6b5ad6d8e232 + depends: + - __osx >=11.0 + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - six + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1192924 + timestamp: 1772171603602 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda + sha256: f6dced0ea4f220abc1278f6217e22ca1c631f6154dd086b0a7a2866589d6b78c + md5: 812e22c5c7859e719ec225ece0c6f2c1 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - setuptools + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-core?source=hash-mapping + size: 481434 + timestamp: 1763151508974 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda + sha256: 307ca29ebf2317bd2561639b1ee0290fd8c03c3450fa302b9f9437d8df6a5280 + md5: 31a0a72f3466682d0ea2ebcbd7d319b8 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - setuptools + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-core?source=hash-mapping + size: 481508 + timestamp: 1763152124940 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda + sha256: 67e209a5e9ebaf08aa36e2a4b9139ff91a7ecee7c17408d0a3a1ea1dc3a67681 + md5: b215a767b5ef6f16347cacebc409e66b + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pyobjc-core 12.1.* + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping + size: 383445 + timestamp: 1763160541362 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda + sha256: 194e188d8119befc952d04157079733e2041a7a502d50340ddde632658799fdc + md5: a6d28c8fc266a3d3c3dae183e25c4d31 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pyobjc-core 12.1.* + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping + size: 376136 + timestamp: 1763160678792 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda + sha256: 9a846065863925b2562126a5c6fecd7a972e84aaa4de9e686ad3715ca506acfa + md5: 49c7d96c58b969585cf09fb01d74e08e + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 14753109 + timestamp: 1772730203101 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda + build_number: 100 + sha256: d0fffc5fde21d1ae350da545dfb9e115a8c53bed8a9c5761f9efd4a5581853c1 + md5: 9991a930e81d3873eba7a299ba783ec4 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + license: Python-2.0 + purls: [] + size: 12966447 + timestamp: 1775615694085 + python_site_packages_path: lib/python3.13/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda + sha256: 984e73d7957460689e10533059de8adb38a308853d298900a37acc58edd84cec + md5: e4b908da7cd496b3fa6798c0f60a2a19 + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 192948 + timestamp: 1770223655988 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda + sha256: 950725516f67c9691d81bb8dde8419581c5332c5da3da10c9ba8cbb1698b825d + md5: 5d0c8b92128c93027632ca8f8dc1190f + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 188763 + timestamp: 1770224094408 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda + sha256: c5d65e1192241d764a68eb0e95ef3ec4800a7e8584260aa2bdcfad0a2d769609 + md5: 9648524ed194922a084f0c2c2c2ada6a + depends: + - python + - __osx >=11.0 + - python 3.11.* *_cpython + - libcxx >=19 + - zeromq >=4.3.5,<4.4.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 359869 + timestamp: 1771717160649 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda + noarch: python + sha256: 2f31f799a46ed75518fae0be75ecc8a1b84360dbfd55096bc2fe8bd9c797e772 + md5: 2f6b79700452ef1e91f45a99ab8ffe5a + depends: + - python + - libcxx >=19 + - __osx >=11.0 + - _python_abi3_support 1.* + - cpython >=3.12 + - zeromq >=4.3.5,<4.4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 191641 + timestamp: 1771717073430 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 + depends: + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 313930 + timestamp: 1765813902568 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda + sha256: 15873755f078583cea046f7ca7fc0d5348d1f29a16a30b73bdb53dd62f2ba379 + md5: 4408829b022e8e0d19365c0c00be00c4 + depends: + - python + - python 3.11.* *_cpython + - __osx >=11.0 + - python_abi 3.11.* *_cp311 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 357600 + timestamp: 1764543142990 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda + sha256: db63344f91e8bfe77703c6764aa9eeafb44d165e286053214722814eabda0264 + md5: 190c2d0d4e98ec97df48cdb74caf44d8 + depends: + - python + - __osx >=11.0 + - python 3.13.* *_cp313 + - python_abi 3.13.* *_cp313 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 358961 + timestamp: 1764543165314 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda + noarch: python + sha256: 91992a557456cbe9980e8ffb0f0d1200f65f741adeefc7ecf568d1935690a7bc + md5: 7151a0851207b88c0031f388a7825e9b + depends: + - python + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 8485007 + timestamp: 1778119519471 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda + sha256: 572923958ec987f3f68e228dfec243c89ab94b50398731215d36e2e040db8703 + md5: 6f12d9ff025ab1875dff67ad779ca29d + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 875022 + timestamp: 1774358570256 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda + sha256: c5b0ee042d8a0b88a3823226dc95b794c042c498aee330aa9b4d78bfad01d099 + md5: 303333dd882dfeb303cc8bfac178464b + depends: + - __osx >=11.0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 883472 + timestamp: 1774358832451 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac + md5: 78a0fe9e9c50d2c381e8ee47e3ea437d + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 83386 + timestamp: 1753484079473 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda + sha256: 2705360c72d4db8de34291493379ffd13b09fd594d0af20c9eefa8a3f060d868 + md5: e85dcd3bde2b10081cdcaeae15797506 + depends: + - __osx >=11.0 + - libcxx >=19 + - krb5 >=1.22.2,<1.23.0a0 + - libsodium >=1.0.21,<1.0.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 245246 + timestamp: 1772476886668 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py311h3485c13_2.conda + sha256: 787e9a5f0a5624fee2af4f58c823bd7933b8ca560e794dd9a821e990b31d2d49 + md5: 5fde0926a521a37d454a5e3162cb6e51 + depends: + - cffi >=1.0.1 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 38502 + timestamp: 1762509668838 +- conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-25.1.0-py313h5ea7bf4_2.conda + sha256: 3f8a1affdfeb2be5289d709e365fc6e386d734773895215cf8cbc5100fa6af9a + md5: eabb4b677b54874d7d6ab775fdaa3d27 + depends: + - cffi >=1.0.1 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/argon2-cffi-bindings?source=hash-mapping + size: 38779 + timestamp: 1762509796090 +- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py311h71c1bcc_0.conda + sha256: f551f6d7f1a62be18e4165772d300d21e0bd925956bcd9c2a605cabf9a2835d0 + md5: a0b8a2723108680aa6bb85fe3e413e76 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=hash-mapping + size: 243538 + timestamp: 1777848744191 +- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.4.0-py313h2a31948_0.conda + sha256: b9c1465c03cb6ff79fb4f2feb21955b9b89783f868c900cad45dbcb8d81ab429 + md5: ef16917e1231df5c6f2ba245c8fe35e4 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=compressed-mapping + size: 240632 + timestamp: 1777848740331 +- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py311hf51aa87_1.conda + sha256: b4cc5ee88f5d19381923519b1f6a1bbc73752f5b1528e4a1df0a3a802e497d13 + md5: fd25556009eae0faab9fc6286150d477 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 170642 + timestamp: 1762497737769 +- conda: https://conda.anaconda.org/conda-forge/win-64/bcrypt-5.0.0-py313hfbe8231_1.conda + sha256: 21baf1316a8160fd3b83e7128803735b107f47c58ba5d5305a372fd6c679d42b + md5: 2a664b5cc93fbc9d7ca595b206a299f0 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/bcrypt?source=hash-mapping + size: 170702 + timestamp: 1762497739995 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda + sha256: 1803c838946d79ef6485ae8c7dafc93e28722c5999b059a34118ef758387a4c9 + md5: b0c459f98ac5ea504a9d9df6242f7ee1 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libbrotlicommon 1.2.0 hfd05255_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 335333 + timestamp: 1764018370925 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py313h3ebfc14_1.conda + sha256: 3558006cd6e836de8dff53cbe5f0b9959f96ea6a6776b4e14f1c524916dd956c + md5: 916a39a0261621b8c33e9db2366dd427 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libbrotlicommon 1.2.0 hfd05255_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 335605 + timestamp: 1764018132514 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda + sha256: c9caca6098e3d92b1a269159b759d757518f2c477fbbb5949cb9fee28807c1f1 + md5: f02335db0282d5077df5bc84684f7ff9 + depends: + - pycparser + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 297941 + timestamp: 1761203850323 +- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py313h5ea7bf4_1.conda + sha256: f867a11f42bb64a09b232e3decf10f8a8fe5194d7e3a216c6bac9f40483bd1c6 + md5: 55b44664f66a2caf584d72196aa98af9 + depends: + - pycparser + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 292681 + timestamp: 1761203203673 +- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py311h2098ed6_0.conda + sha256: a6fca5c54f019724d08fc3d9e54c60ca8c0c8aa8b54571fec3e713bbb64a55c3 + md5: 27def055167d830e4ce6c6821eaee591 + depends: + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1645132 + timestamp: 1777966325193 +- conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-48.0.0-py313hf5c5e30_0.conda + sha256: 1fbf66094059379d72f06d3cbb9df5277352a95d25a68d55d1dd60fa6acca5c6 + md5: c216777102e0b49ed307e181df3903d2 + depends: + - cffi >=2.0 + - openssl >=3.5.6,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT + license_family: BSD + purls: + - pkg:pypi/cryptography?source=hash-mapping + size: 1646298 + timestamp: 1777966340031 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py311h5dfdfe8_0.conda + sha256: 661e5c582b1f853a46a78d4bb6e55f2bfdac66e68d015e111f1580a11c28abbf + md5: 683be2cd10e80a367790b3083ce529b7 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 3940002 + timestamp: 1769745017274 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py313h927ade5_0.conda + sha256: f6fe9cbd9e3d3c09f173eeb43676a58bc6169e97da0d190e0201e40828a3a62b + md5: 75eb3091b05924429a3a8d2a9bbdfac2 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 4003589 + timestamp: 1769745018248 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761 + md5: 4432f52dc0c8eb6a7a6abc00a037d93c + depends: + - openssl >=3.5.5,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 751055 + timestamp: 1769769688841 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda + sha256: 2d81d647c1f01108803457cac999b947456f44dd0a3c2325395677feacaeca67 + md5: 264e350e035092b5135a2147c238aec4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.0.* + license: MIT + license_family: MIT + purls: [] + size: 71094 + timestamp: 1777846223617 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 + md5: 8f83619ab1588b98dd99c90b0bfc5c6d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 106486 + timestamp: 1775825663227 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 + md5: e4a9fc2bba3b022dad998c78856afe47 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 89411 + timestamp: 1769482314283 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.21-h6a83c73_3.conda + sha256: d915f4fa8ebbf237c7a6e511ed458f2cfdc7c76843a924740318a15d0dd33d6d + md5: da2aa614d16a795b3007b6f4a1318a81 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: ISC + purls: [] + size: 276860 + timestamp: 1772479407566 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda + sha256: e70562450332ca8954bc16f3455468cca5ef3695c7d7187ecc87f8fc3c70e9eb + md5: 7fea434a17c323256acc510a041b80d7 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1304178 + timestamp: 1777986510497 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 + md5: dbabbd6234dea34040e631f87676292f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + purls: [] + size: 58347 + timestamp: 1774072851498 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py311h3f79411_1.conda + sha256: 3d37fb1900e31131f84549560e7a4bfea5f39aa3ecd73345fef1f33975cf0baa + md5: f55de41c947bdd2ff9bbeffedf8089f7 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 29362 + timestamp: 1772445178723 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py313hd650c13_1.conda + sha256: 9dc626b6c00bc2dbd2494df689876ff675b93d92636ba5df8e37b99040a1f6bc + md5: 5cc690ddf943700e0ef50a265df31f03 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 28992 + timestamp: 1772445161959 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py311h3485c13_0.conda + sha256: d096ad02a47a61aeeade2ad3639cc300adf950790cca097717040d46ca5bff52 + md5: 6e6fd9a9012358254bebee33eb3d7f71 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 199272 + timestamp: 1776337711230 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgspec-0.21.1-py313h5ea7bf4_0.conda + sha256: 4e70a7b9bee6b9dadd1f038da6fcf1627cc53581d1cc01355b66d638ae55c0e3 + md5: 96575971ffc81497b83bf321f0b9e945 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/msgspec?source=hash-mapping + size: 201017 + timestamp: 1776337591817 +- conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.8.2-h80d1838_0.conda + sha256: 5e38e51da1aa4bc352db9b4cec1c3e25811de0f4408edaa24e009a64de6dbfdf + md5: e626ee7934e4b7cb21ce6b721cff8677 + license: MIT + license_family: MIT + purls: [] + size: 31271315 + timestamp: 1774517904472 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + sha256: feb5815125c60f2be4a411e532db1ed1cd2d7261a6a43c54cb6ae90724e2e154 + md5: 05c7d624cff49dbd8db1ad5ba537a8a3 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 9410183 + timestamp: 1775589779763 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda + sha256: 32da17824abadd1f5b46faedfa4964c7b1817b11887c2e8bb4e48628da51b93a + md5: fd968cdacc7967efd0ff5ef1805b812c + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 249478 + timestamp: 1769678166841 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda + sha256: 3ec3373748f83069bef93b540de416e637ee30231b222d5df8f712e93f2f9195 + md5: 761b299a6289c77459defea3563f8fc0 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 246062 + timestamp: 1769678176886 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda + sha256: 4cf860418a6a1a678bcc23bc29a83f4f0916682fd6ab1ff209b4e5ee3dc5e15f + md5: 85efdb748cbec9210e718c4a8860749c + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1898998 + timestamp: 1778084255268 +- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda + sha256: 6466b7e441adb71e29308de2a87c9787d5d0100601ede2d02ed4f85c251699d6 + md5: 9981bc46be6341306a5473b290b2f366 + depends: + - python + - typing-extensions >=4.6.0,!=4.7.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core?source=hash-mapping + size: 1888029 + timestamp: 1778084253466 +- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda + sha256: cd35ad681895b45f578bac8fd8dafc87116c2db42489dda9bef76ff3518bbc73 + md5: e2197089006b3cda7e03c7a51fa7050e + depends: + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - six + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1147862 + timestamp: 1772171327674 +- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda + sha256: 0960e727d0bd70e07bca0c049c4c4afa0b41bcea050135db49f54c1c0c02ed7f + md5: 99b7617a643bed6a403fc908c1e167f0 + depends: + - cffi >=1.4.1 + - libsodium >=1.0.21,<1.0.22.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - six + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/pynacl?source=hash-mapping + size: 1186552 + timestamp: 1772171311072 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda + sha256: a1f1031088ce69bc99c82b95980c1f54e16cbd5c21f042e9c1ea25745a8fc813 + md5: d09dbf470b41bca48cbe6a78ba1e009b + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 18416208 + timestamp: 1772728847666 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda + build_number: 100 + sha256: b8108d7f83f71fb15fbb4a263406c2065a8990b3d7eba2cbd7a3075b9a6392ba + md5: 7065f7067762c4c2bda1912f18d16239 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.5,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.52.0,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - python_abi 3.13.* *_cp313 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Python-2.0 + purls: [] + size: 16618694 + timestamp: 1775613654892 + python_site_packages_path: Lib/site-packages +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda + sha256: e3ef7e0cc53111ab81b8a9dd3eabc1374d7420d4c9fce3c8631e73310203ad55 + md5: c1cfe9f5d8e278cc4d2d4c7b0126634d + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 6729388 + timestamp: 1756487145061 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda + sha256: 87eaeb79b5961e0f216aa840bc35d5f0b9b123acffaecc4fda4de48891901f20 + md5: 1ce4f826332dca56c76a5b0cc89fb19e + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 6695114 + timestamp: 1756487139550 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda + sha256: b1f6b3a907e36f7af486faf3892f47fab42993c13c934cc19855bbae227f2b18 + md5: e5dd9afed138ff193d4593f1b15a388b + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - winpty + license: MIT + license_family: MIT + purls: + - pkg:pypi/pywinpty?source=hash-mapping + size: 215911 + timestamp: 1759557817579 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda + sha256: d34a7cd0a4a7dc79662cb6005e01d630245d9a942e359eb4d94b2fb464ed2552 + md5: 8f01ed27e2baa455e753301218e054fd + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - winpty + license: MIT + license_family: MIT + purls: + - pkg:pypi/pywinpty?source=hash-mapping + size: 216075 + timestamp: 1759556799508 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda + sha256: 301c3ba100d25cd5ae37895988ee3ab986210d4d972aa58efed948fbe857773d + md5: a0153c033dc55203e11d1cac8f6a9cf2 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 187108 + timestamp: 1770223467913 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda + sha256: dfaed50de8ee72a51096163b87631921688851001e38c78a841eba1ae8b35889 + md5: c1bdb8dd255c79fb9c428ad25cc6ee54 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 180992 + timestamp: 1770223457761 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda + sha256: d37e831618e8df0506d32e16820adab550b74b36d039da753f7543bb967b700d + md5: 0ad824e928af5d6200a97649d810ab2b + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + - zeromq >=4.3.5,<4.3.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 363314 + timestamp: 1771716977369 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda + noarch: python + sha256: d84bcc19a945ca03d1fd794be3e9896ab6afc9f691d58d9c2da514abe584d4df + md5: eb1ec67a70b4d479f7dd76e6c8fe7575 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - zeromq >=4.3.5,<4.3.6.0a0 + - _python_abi3_support 1.* + - cpython >=3.12 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 183235 + timestamp: 1771716967192 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda + sha256: 6edeab1412def450e72f0e96a5d8bb31a2a0b4e56624699c916d3bafd4d9b475 + md5: 43ab63451a9df29f2c499da524665de9 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.11.* *_cp311 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 241288 + timestamp: 1764543026991 +- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda + sha256: 27bd383787c0df7a0a926b11014fd692d60d557398dcf1d50c55aa2378507114 + md5: 58ae648b12cfa6df3923b5fd219931cb + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 243419 + timestamp: 1764543047271 +- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda + noarch: python + sha256: 9b47c39449fd0102315bb62bd632707a754d32cf6c6f08d2a9c74b0a476f2282 + md5: 2db0d3419f3e6fc05516da561f81cda5 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 9719930 + timestamp: 1778119435755 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 + md5: 0481bfd9814bf525bd4b3ee4b51494c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: TCL + license_family: BSD + purls: [] + size: 3526350 + timestamp: 1769460339384 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda + sha256: 71f58fe09f7729ad82c8eb942e775ddeffcef454483911d19d1041ac5d81eec3 + md5: b004afcc680af88cb877978e71d42667 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 878544 + timestamp: 1774358187588 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda + sha256: b97fab804ab457cf4157103289317e3619e801a77410e756bb35c6223418cc6e + md5: 7d53f0d25ad5fd7d6962ce4eb385fb07 + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 883689 + timestamp: 1774358224157 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + purls: [] + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f + depends: + - vc14_runtime >=14.44.35208 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_34 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 115235 + timestamp: 1767320173250 +- conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 + sha256: 9df10c5b607dd30e05ba08cbd940009305c75db242476f4e845ea06008b0a283 + md5: 1cee351bf20b830d991dbe0bc8cd7dfe + license: MIT + license_family: MIT + purls: [] + size: 1176306 +- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 + md5: 433699cba6602098ae8957a323da2664 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 63944 + timestamp: 1753484092156 +- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda + sha256: b8568dfde46edf3455458912ea6ffb760e4456db8230a0cf34ecbc557d3c275f + md5: 1ab0237036bfb14e923d6107473b0021 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libsodium >=1.0.21,<1.0.22.0a0 + - krb5 >=1.22.2,<1.23.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 265665 + timestamp: 1772476832995 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 388453 + timestamp: 1764777142545 +- pypi: . + name: easyreflectometry + requires_dist: + - bumps + - easyscience @ git+https://github.com/easyscience/corelib@develop + - orsopy + - pooch + - refl1d>=1.0.0 + - refnx + - scipp + - svglib<1.6 ; sys_platform == 'darwin' or sys_platform == 'linux' + - xhtml2pdf + - arviz ; extra == 'dev' + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - plopp ; extra == 'dev' + - plotly ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.11' +- pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + name: easyscience + version: 2.3.1+dev8 + requires_dist: + - asteval + - bumps + - dfo-ls + - lmfit + - numpy + - scipp + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - ipykernel ; extra == 'dev' + - ipympl ; extra == 'dev' + - ipython ; extra == 'dev' + - ipywidgets ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterlab ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - matplotlib ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pooch ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl + name: backrefs + version: '7.0' + sha256: f2c52955d631b9e1ac4cd56209f0a3a946d592b98e7790e77699339ae01c102a + requires_dist: + - regex ; extra == 'extras' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl + name: oscrypto + version: 1.3.0 + sha256: 2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085 + requires_dist: + - asn1crypto>=1.5.1 +- pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl + name: lxml + version: 6.1.0 + sha256: 183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + name: pyyaml-env-tag + version: '1.1' + sha256: 17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 + requires_dist: + - pyyaml + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: python-bidi + version: 0.6.9 + sha256: 29e40e02bf2bddec225730eb3ba9f4ca948dced9877358458b74d7a447d936ac + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + name: python-socketio + version: 5.16.1 + sha256: a3eb1702e92aa2f2b5d3ba00261b61f062cce51f1cfb6900bf3ab4d1934d2d35 + requires_dist: + - bidict>=0.21.0 + - python-engineio>=4.11.0 + - requests>=2.21.0 ; extra == 'client' + - websocket-client>=0.54.0 ; extra == 'client' + - aiohttp>=3.4 ; extra == 'asyncio-client' + - tox ; extra == 'dev' + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/08/03/69347590f1cf4a6d5a4944bb6099e6d37f334784f16062234e1f892fdb1d/lxml-6.1.0-cp313-cp313-macosx_10_13_universal2.whl + name: lxml + version: 6.1.0 + sha256: a0092f2b107b69601adf562a57c956fbb596e05e3e6651cabd3054113b007e45 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl + name: kiwisolver + version: 1.5.0 + sha256: 0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + name: frozenlist + version: 1.8.0 + sha256: ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl + name: coverage + version: 7.13.5 + sha256: 941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl + name: pypdf + version: 6.10.2 + sha256: aa53be9826655b51c96741e5d7983ca224d898ac0a77896e64636810517624aa + requires_dist: + - typing-extensions>=4.0 ; python_full_version < '3.11' + - cryptography ; extra == 'crypto' + - pycryptodome ; extra == 'cryptodome' + - flit ; extra == 'dev' + - pip-tools ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-socket ; extra == 'dev' + - pytest-timeout ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - wheel ; extra == 'dev' + - myst-parser ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - cryptography ; extra == 'full' + - pillow>=8.0.0 ; extra == 'full' + - pillow>=8.0.0 ; extra == 'image' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0d/1f/d398de1612f7a611e22d743280339c9af4903675635e41be3370091c704b/arviz_stats-1.1.0-py3-none-any.whl + name: arviz-stats + version: 1.1.0 + sha256: ed47334ccff8670a0b90a50e1a37e7257268084eb3436e6b7b15e623f1001947 + requires_dist: + - numpy>=2 + - scipy>=1.13 + - sphinx-book-theme ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - numpydoc ; extra == 'doc' + - sphinx<9 ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - h5netcdf[h5py] ; extra == 'doc' + - sphinx-autosummary-accessors ; extra == 'doc' + - numba ; extra == 'numba' + - xarray-einstats[einops,numba] ; extra == 'numba' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest ; extra == 'test-xarray' + - pytest-cov ; extra == 'test-xarray' + - h5netcdf[h5py] ; extra == 'test-xarray' + - arviz-base>=1.1,<1.2 ; extra == 'xarray' + - xarray-einstats ; extra == 'xarray' + - xarray>=2024.11.0 ; extra == 'xarray' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + name: contourpy + version: 1.3.3 + sha256: 23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl + name: build + version: 1.5.0 + sha256: 13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f + requires_dist: + - packaging>=24.0 + - pyproject-hooks + - colorama ; os_name == 'nt' + - importlib-metadata>=4.6 ; python_full_version < '3.10.2' + - tomli>=1.1.0 ; python_full_version < '3.11' + - keyring ; extra == 'keyring' + - uv>=0.1.18 ; extra == 'uv' + - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv' + - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + name: aiohappyeyeballs + version: 2.6.1 + sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + name: pyparsing + version: 3.3.2 + sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d + requires_dist: + - railroad-diagrams ; extra == 'diagrams' + - jinja2 ; extra == 'diagrams' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + name: blinker + version: 1.9.0 + sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl + name: griffelib + version: 2.0.2 + sha256: 925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1 + requires_dist: + - pip>=24.0 ; extra == 'pypi' + - platformdirs>=4.2 ; extra == 'pypi' + - wheel>=0.42 ; extra == 'pypi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: 2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/12/aa/fb2a0649fdeef5ab7072d221e8f4df164098792c813af6c87e2581cfa860/mpltoolbox-26.2.0-py3-none-any.whl + name: mpltoolbox + version: 26.2.0 + sha256: cd2668db4216fc4d7c2ba37974961aa61445f1517527b645b6082930e35ba7f0 + requires_dist: + - matplotlib + - ipympl ; extra == 'test' + - pytest>=8.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: 5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + name: interrogate + version: 1.7.0 + sha256: b13ff4dd8403369670e2efe684066de9fcb868ad9d7f2b4095d8112142dc9d12 + requires_dist: + - attrs + - click>=7.1 + - colorama + - py + - tabulate + - tomli ; python_full_version < '3.11' + - cairosvg ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-autobuild ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-mock ; extra == 'dev' + - coverage[toml] ; extra == 'dev' + - wheel ; extra == 'dev' + - pre-commit ; extra == 'dev' + - sphinx ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - cairosvg ; extra == 'png' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-mock ; extra == 'tests' + - coverage[toml] ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl + name: mkdocs-jupyter + version: 0.26.3 + sha256: cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82 + requires_dist: + - ipykernel>6.0.0,<8 + - jupytext>1.13.8,<2 + - mkdocs-material>9.0.0 + - mkdocs>=1.4.0,<2 + - nbconvert>=7.2.9,<8 + - pygments>2.12.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/14/4b/d3c79495dee4831b8bebca2790e72cb90f0c5849c940570a7c7e5b70b952/chardet-7.4.3-cp311-cp311-macosx_11_0_arm64.whl + name: chardet + version: 7.4.3 + sha256: 7005c88da26fd95d8abb8acbe6281d833e9a9181b03cf49b4546c4555389bd97 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/15/fe/b426215b6843ee70285521e2dd52f08a32096fe1d68e5b92fbdaffdf8ca3/diffpy_pdffit2-1.6.0-cp313-cp313-win_amd64.whl + name: diffpy-pdffit2 + version: 1.6.0 + sha256: f1bba407eac8ff8ef1264ad5a1d3dff840e2d0a5f71e9fb0c0b9b06d5a8eb139 + requires_dist: + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl + name: spglib + version: 2.6.0 + sha256: ff1632524f6ac0031423474e48d6b69f4932ecb7eb4446a501f59619e2b5cbc9 + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + name: jupytext + version: 1.19.1 + sha256: d8975035155d034bdfde5c0c37891425314b7ea8d3a6c4b5d18c294348714cd9 + requires_dist: + - markdown-it-py>=1.0 + - mdit-py-plugins + - nbformat + - packaging + - pyyaml + - tomli ; python_full_version < '3.11' + - autopep8 ; extra == 'dev' + - black ; extra == 'dev' + - flake8 ; extra == 'dev' + - gitpython ; extra == 'dev' + - ipykernel ; extra == 'dev' + - isort ; extra == 'dev' + - jupyter-fs[fs]>=1.0 ; extra == 'dev' + - jupyter-server!=2.11 ; extra == 'dev' + - marimo>=0.17.6,<=0.19.4 ; extra == 'dev' + - nbconvert ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-asyncio ; extra == 'dev' + - pytest-cov>=2.6.1 ; extra == 'dev' + - pytest-randomly ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-gallery>=0.8 ; extra == 'dev' + - myst-parser ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-randomly ; extra == 'test' + - pytest-xdist ; extra == 'test' + - black ; extra == 'test-cov' + - ipykernel ; extra == 'test-cov' + - jupyter-server!=2.11 ; extra == 'test-cov' + - nbconvert ; extra == 'test-cov' + - pytest ; extra == 'test-cov' + - pytest-asyncio ; extra == 'test-cov' + - pytest-cov>=2.6.1 ; extra == 'test-cov' + - pytest-randomly ; extra == 'test-cov' + - pytest-xdist ; extra == 'test-cov' + - autopep8 ; extra == 'test-external' + - black ; extra == 'test-external' + - flake8 ; extra == 'test-external' + - gitpython ; extra == 'test-external' + - ipykernel ; extra == 'test-external' + - isort ; extra == 'test-external' + - jupyter-fs[fs]>=1.0 ; extra == 'test-external' + - jupyter-server!=2.11 ; extra == 'test-external' + - marimo>=0.17.6,<=0.19.4 ; extra == 'test-external' + - nbconvert ; extra == 'test-external' + - pre-commit ; extra == 'test-external' + - pytest ; extra == 'test-external' + - pytest-asyncio ; extra == 'test-external' + - pytest-randomly ; extra == 'test-external' + - pytest-xdist ; extra == 'test-external' + - sphinx ; extra == 'test-external' + - sphinx-gallery>=0.8 ; extra == 'test-external' + - black ; extra == 'test-functional' + - pytest ; extra == 'test-functional' + - pytest-asyncio ; extra == 'test-functional' + - pytest-randomly ; extra == 'test-functional' + - pytest-xdist ; extra == 'test-functional' + - black ; extra == 'test-integration' + - ipykernel ; extra == 'test-integration' + - jupyter-server!=2.11 ; extra == 'test-integration' + - nbconvert ; extra == 'test-integration' + - pytest ; extra == 'test-integration' + - pytest-asyncio ; extra == 'test-integration' + - pytest-randomly ; extra == 'test-integration' + - pytest-xdist ; extra == 'test-integration' + - bash-kernel ; extra == 'test-ui' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl + name: sqlalchemy + version: 2.0.49 + sha256: 12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl + name: xarray-einstats + version: 0.9.1 + sha256: 777339524e85d066f2ef9ed1e3a3fb63aead4c1065fd1406f30dfa4de58ce063 + requires_dist: + - numpy>=1.25 + - scipy>=1.11 + - xarray>=2023.6.0 + - furo ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - numpydoc ; extra == 'doc' + - sphinx>=5 ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - watermark ; extra == 'doc' + - matplotlib ; extra == 'doc' + - sphinx-togglebutton ; extra == 'doc' + - einops ; extra == 'einops' + - numba>=0.55 ; extra == 'numba' + - hypothesis ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - packaging ; extra == 'test' + - scipy>=1.15 ; extra == 'test' + - preliz>=0.19 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + name: contourpy + version: 1.3.3 + sha256: 1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl + name: xarray-einstats + version: 0.10.0 + sha256: fa3169b46cee29092db820d8bbc203148bada4fc970ee75e62cbf3dd7c5a8945 + requires_dist: + - numpy>=2.0 + - scipy>=1.13 + - xarray>=2024.2.0 + - furo ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - numpydoc ; extra == 'doc' + - sphinx>=5 ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - watermark ; extra == 'doc' + - matplotlib ; extra == 'doc' + - sphinx-togglebutton ; extra == 'doc' + - einops ; extra == 'einops' + - numba>=0.55 ; extra == 'numba' + - hypothesis ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - packaging ; extra == 'test' + - scipy>=1.15 ; extra == 'test' + - preliz>=0.19 ; extra == 'test' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/1b/b3/5d0e77ea774bd3224321c248880ea0c0379000ac5c2bb6d77609549de247/chardet-7.4.3-cp313-cp313-win_amd64.whl + name: chardet + version: 7.4.3 + sha256: e1b98790c284ff813f18f7cf7de5f05ea2435a080030c7f1a8318f3a4f80b131 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl + name: reportlab + version: 4.5.0 + sha256: b8cc8996947d84e805368b47b2376070966f091d029351a0d8a1f238984c2c7f + requires_dist: + - pillow>=9.0.0 + - charset-normalizer + - rl-accel>=0.9.0,<1.1 ; extra == 'accel' + - rl-renderpm>=4.0.3,<4.1 ; extra == 'renderpm' + - rlpycairo>=0.2.0,<1 ; extra == 'pycairo' + - freetype-py>=2.3.0,<2.4 ; extra == 'pycairo' + - rlbidi ; extra == 'bidi' + - uharfbuzz ; extra == 'shaping' + requires_python: '>=3.9,<4' +- pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + name: versioningit + version: 3.3.0 + sha256: 23b1db3c4756cded9bd6b0ddec6643c261e3d0c471707da3e0b230b81ce53e4b + requires_dist: + - importlib-metadata>=3.6 ; python_full_version < '3.10' + - packaging>=17.1 + - tomli>=1.2,<3.0 ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + name: dill + version: 0.4.1 + sha256: 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d + requires_dist: + - objgraph>=1.7.2 ; extra == 'graph' + - gprof2dot>=2022.7.29 ; extra == 'profile' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl + name: annotated-doc + version: 0.0.4 + sha256: 571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + name: nbstripout + version: 0.9.1 + sha256: ca027ee45742ee77e4f8e9080254f9a707f1161ba11367b82fdf4a29892c759e + requires_dist: + - nbformat + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: 61c2fd96d72b983a9891b2598f286befd4ad262161a609c92dc1652544b46b76 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' - odfpy>=1.4.1 ; extra == 'excel' - openpyxl>=3.1.5 ; extra == 'excel' - python-calamine>=0.3.0 ; extra == 'excel' @@ -9014,536 +9246,556 @@ packages: - xlsxwriter>=3.2.0 ; extra == 'all' - zstandard>=0.23.0 ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: pandas - version: 3.0.2 - sha256: 5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e +- pypi: https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl + name: gitpython + version: 3.1.50 + sha256: d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 + requires_dist: + - gitdb>=4.0.1,<5 + - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' + - coverage[toml] ; extra == 'test' + - ddt>=1.1.1,!=1.4.3 ; extra == 'test' + - mock ; python_full_version < '3.8' and extra == 'test' + - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' + - pre-commit ; extra == 'test' + - pytest>=7.3.1 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-instafail ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-sugar ; extra == 'test' + - typing-extensions ; python_full_version < '3.11' and extra == 'test' + - sphinx>=7.4.7,<8 ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/21/0e/8459ca4413e1a21a06c97d134bfaf18adfd27cea068813dc0faae06cbf00/cssselect2-0.9.0-py3-none-any.whl + name: cssselect2 + version: 0.9.0 + sha256: 6a99e5f91f9a016a304dd929b0966ca464bcfda15177b6fb4a118fc0fb5d9563 + requires_dist: + - tinycss2 + - webencodings + - sphinx ; extra == 'doc' + - furo ; extra == 'doc' + - pytest ; extra == 'test' + - ruff ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + name: mkdocs + version: 1.6.1 + sha256: db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e + requires_dist: + - click>=7.0 + - colorama>=0.4 ; sys_platform == 'win32' + - ghp-import>=1.0 + - importlib-metadata>=4.4 ; python_full_version < '3.10' + - jinja2>=2.11.1 + - markdown>=3.3.6 + - markupsafe>=2.0.1 + - mergedeep>=1.3.4 + - mkdocs-get-deps>=0.2.0 + - packaging>=20.5 + - pathspec>=0.11.1 + - pyyaml-env-tag>=0.1 + - pyyaml>=5.1 + - watchdog>=2.0 + - babel>=2.9.0 ; extra == 'i18n' + - babel==2.9.0 ; extra == 'min-versions' + - click==7.0 ; extra == 'min-versions' + - colorama==0.4 ; sys_platform == 'win32' and extra == 'min-versions' + - ghp-import==1.0 ; extra == 'min-versions' + - importlib-metadata==4.4 ; python_full_version < '3.10' and extra == 'min-versions' + - jinja2==2.11.1 ; extra == 'min-versions' + - markdown==3.3.6 ; extra == 'min-versions' + - markupsafe==2.0.1 ; extra == 'min-versions' + - mergedeep==1.3.4 ; extra == 'min-versions' + - mkdocs-get-deps==0.2.0 ; extra == 'min-versions' + - packaging==20.5 ; extra == 'min-versions' + - pathspec==0.11.1 ; extra == 'min-versions' + - pyyaml-env-tag==0.1 ; extra == 'min-versions' + - pyyaml==5.1 ; extra == 'min-versions' + - watchdog==2.0 ; extra == 'min-versions' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl + name: py3dmol + version: 2.5.4 + sha256: 32806726b5310524a2b5bfee320737f7feef635cafc945c991062806daa9e43a + requires_dist: + - ipython ; extra == 'ipython' +- pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + name: nbqa + version: 1.9.1 + sha256: 95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5 + requires_dist: + - autopep8>=1.5 + - ipython>=7.8.0 + - tokenize-rt>=3.2.0 + - tomli + - black ; extra == 'toolchain' + - blacken-docs ; extra == 'toolchain' + - flake8 ; extra == 'toolchain' + - isort ; extra == 'toolchain' + - jupytext ; extra == 'toolchain' + - mypy ; extra == 'toolchain' + - pylint ; extra == 'toolchain' + - pyupgrade ; extra == 'toolchain' + - ruff ; extra == 'toolchain' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + name: mkdocs-autorefs + version: 1.4.4 + sha256: 834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089 + requires_dist: + - markdown>=3.3 + - markupsafe>=2.0.1 + - mkdocs>=1.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + name: pooch + version: 1.9.0 + sha256: f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b + requires_dist: + - platformdirs>=2.5.0 + - packaging>=20.0 + - requests>=2.19.0 + - tqdm>=4.41.0,<5.0.0 ; extra == 'progress' + - paramiko>=2.7.0 ; extra == 'sftp' + - xxhash>=1.4.3 ; extra == 'xxhash' + - pytest-httpserver ; extra == 'test' + - pytest-localftpserver ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl + name: msgpack + version: 1.1.2 + sha256: d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.5.0 + sha256: 332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl + name: mkdocs-material + version: 9.7.6 + sha256: 71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba + requires_dist: + - babel>=2.10 + - backrefs>=5.7.post1 + - colorama>=0.4 + - jinja2>=3.1 + - markdown>=3.2 + - mkdocs-material-extensions>=1.3 + - mkdocs>=1.6,<2 + - paginate>=0.5 + - pygments>=2.16 + - pymdown-extensions>=10.2 + - requests>=2.30 + - mkdocs-git-committers-plugin-2>=1.1 ; extra == 'git' + - mkdocs-git-revision-date-localized-plugin>=1.2.4 ; extra == 'git' + - cairosvg>=2.6 ; extra == 'imaging' + - pillow>=10.2 ; extra == 'imaging' + - mkdocs-minify-plugin>=0.7 ; extra == 'recommended' + - mkdocs-redirects>=1.2 ; extra == 'recommended' + - mkdocs-rss-plugin>=1.6 ; extra == 'recommended' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + name: mergedeep + version: 1.3.4 + sha256: 70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307 + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl + name: spglib + version: 2.6.0 + sha256: 12db7a0d6ad84c55e61eda67590a438edeb48e57ffd5df868cd931b57fb8c630 + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 26.3.1 + sha256: 993706e7c31f0317be2db5f528f9142ba67b2e52d7af174fcad195f702e1d6c7 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/2f/c8/005d1de3af80f54411703d1263a0b9d31276411ec9f273d9432c59b17299/arviz_plots-1.1.0-py3-none-any.whl + name: arviz-plots + version: 1.1.0 + sha256: 5c7ab5b0c7c29cda6ddb5e04c699c70285fe68a76d2b1b42302c69a85742adde + requires_dist: + - arviz-base>=1.1,<1.2 + - arviz-stats[xarray]>=1.1,<1.2 + - bokeh>=3.4 ; extra == 'bokeh' + - sphinx-book-theme ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - numpydoc ; extra == 'doc' + - sphinx>=6 ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - h5netcdf[h5py] ; extra == 'doc' + - plotly<6 ; extra == 'doc' + - matplotlib>=3.9 ; extra == 'matplotlib' + - plotly>=5.19 ; extra == 'plotly' + - webcolors ; extra == 'plotly' + - hypothesis ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - h5netcdf[h5py] ; extra == 'test' + - kaleido ; extra == 'test' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl + name: python-discovery + version: 1.3.0 + sha256: 441d9ced3dfce36e113beb35ca302c71c7ef06f3c0f9c227a0b9bb3bd49b9e9f requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: pandas - version: 3.0.2 - sha256: 61c2fd96d72b983a9891b2598f286befd4ad262161a609c92dc1652544b46b76 + - filelock>=3.15.4 + - platformdirs>=4.3.6,<5 + - furo>=2025.12.19 ; extra == 'docs' + - sphinx-autodoc-typehints>=3.6.3 ; extra == 'docs' + - sphinx>=9.1 ; extra == 'docs' + - sphinxcontrib-mermaid>=2 ; extra == 'docs' + - covdefaults>=2.3 ; extra == 'testing' + - coverage>=7.5.4 ; extra == 'testing' + - pytest-mock>=3.14 ; extra == 'testing' + - pytest>=8.3.5 ; extra == 'testing' + - setuptools>=75.1 ; extra == 'testing' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/31/b8/69f5565f1a280d032525878a86511eebed0645818492feeb169dfb20ae8e/llvmlite-0.47.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: llvmlite + version: 0.47.0 + sha256: 2699a74321189e812d476a43d6d7f652f51811e7b5aad9d9bba842a1c7927acb + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + name: mkdocstrings-python + version: 2.0.3 + sha256: 0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl - name: pandas - version: 3.0.2 - sha256: ed72cb3f45190874eb579c64fa92d9df74e98fd63e2be7f62bce5ace0ade61df + - mkdocstrings>=0.30 + - mkdocs-autorefs>=1.4 + - griffelib>=2.0 + - typing-extensions>=4.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + name: distlib + version: 0.4.0 + sha256: 9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 +- pypi: https://files.pythonhosted.org/packages/33/b2/986d1220f6ee931e338d272bc1f3ec02cfe5f9b5fad84e95afdad57f1ebc/format_docstring-0.2.7-py3-none-any.whl + name: format-docstring + version: 0.2.7 + sha256: c9d50eafebe0f260e3270ca662ff3a0ed4050f64d95e352f8c5f88d9aede42d6 + requires_dist: + - click>=8.0 + - jupyter-notebook-parser>=0.1.4 + - tomli>=1.1.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/33/eb/f9f1ded8e4db9638f9530c3782eb01f5ab04945f4cb9e597a51c203fa4c5/diffpy_pdffit2-1.6.0.tar.gz + name: diffpy-pdffit2 + version: 1.6.0 + sha256: 11a65466f8790f5ac7ae45f2f3fc0d5d116d156d274bcfc079df653123d080e2 + requires_dist: + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + name: tokenize-rt + version: 6.2.0 + sha256: a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/34/0b/b9d1911cfefa61399821dfb37f486d83e0f42630a8d12f7194270c417002/llvmlite-0.47.0-cp311-cp311-macosx_11_0_arm64.whl + name: llvmlite + version: 0.47.0 + sha256: 74090f0dcfd6f24ebbef3f21f11e38111c4d7e6919b54c4416e1e357c3446b07 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl + name: coverage + version: 7.13.5 + sha256: 145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/35/8c/a917ef8741729ef8b3228f815240f4859717e600f9498359a6c411ed6992/crysfml-0.6.2-cp313-cp313-macosx_14_0_arm64.whl + name: crysfml + version: 0.6.2 + sha256: 0010858646240f6c64e2711c33ccfffd94ee6602859babd1186785e28d6c5c11 + requires_dist: + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: 37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl - name: pandas - version: 3.0.2 - sha256: 07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991 +- pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl + name: scipp + version: 26.3.1 + sha256: 03c6dbf8936a2ed62587c5abe8ab5266a5098834a0709321ce799bd1328eb3e6 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl - name: pandas - version: 3.0.2 - sha256: dbbd4aa20ca51e63b53bbde6a0fa4254b1aaabb74d2f542df7a7959feb1d760c +- pypi: https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl + name: fonttools + version: 4.62.1 + sha256: 7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - sha256: 2bb9ba9857f4774b85900c2562f7e711d08dd48e2add9bee4e1612fbee27e16f - md5: 457c2c8c08e54905d6954e79cb5b5db9 - depends: - - python !=3.0,!=3.1,!=3.2,!=3.3 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pandocfilters?source=hash-mapping - size: 11627 - timestamp: 1631603397334 -- conda: https://conda.anaconda.org/conda-forge/noarch/paramiko-4.0.0-pyhd8ed1ab_0.conda - sha256: ce76d5a1fc6c7ef636cbdbf14ce2d601a1bfa0dd8d286507c1fd02546fccb94b - md5: 1a884d2b1ea21abfb73911dcdb8342e4 - depends: - - bcrypt >=3.2 - - cryptography >=3.3 - - invoke >=2.0 - - pynacl >=1.5 - - python >=3.9 - license: LGPL-2.1-or-later - license_family: LGPL - purls: - - pkg:pypi/paramiko?source=hash-mapping - size: 159896 - timestamp: 1755102147074 -- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - sha256: 611882f7944b467281c46644ffde6c5145d1a7730388bcde26e7e86819b0998e - md5: 39894c952938276405a1bd30e4ce2caf - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/parso?source=compressed-mapping - size: 82472 - timestamp: 1777722955579 -- pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl - name: partd - version: 1.4.2 - sha256: 978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + name: lmfit + version: 1.3.4 + sha256: afce1593b42324d37ae2908249b0c55445e2f4c1a0474ff706a8e2f7b5d949fa + requires_dist: + - asteval>=1.0 + - numpy>=1.24 + - scipy>=1.10.0 + - uncertainties>=3.2.2 + - dill>=0.3.4 + - build ; extra == 'dev' + - check-wheel-contents ; extra == 'dev' + - flake8-pyproject ; extra == 'dev' + - pre-commit ; extra == 'dev' + - twine ; extra == 'dev' + - cairosvg ; extra == 'doc' + - corner ; extra == 'doc' + - emcee>=3.0.0 ; extra == 'doc' + - ipykernel ; extra == 'doc' + - jupyter-sphinx>=0.2.4 ; extra == 'doc' + - matplotlib ; extra == 'doc' + - numdifftools ; extra == 'doc' + - pandas ; extra == 'doc' + - pillow ; extra == 'doc' + - pycairo ; sys_platform == 'win32' and extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-gallery>=0.10 ; extra == 'doc' + - sphinxcontrib-svg2pdfconverter ; extra == 'doc' + - sympy ; extra == 'doc' + - coverage ; extra == 'test' + - flaky ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - lmfit[dev,doc,test] ; extra == 'all' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl + name: xraydb + version: 4.5.8 + sha256: 2215baafa6a03d00d0254a94525aafc6493c8c285e4ac4477fbd6271b25e6a51 + requires_dist: + - numpy>=1.19 + - scipy>=1.6 + - sqlalchemy>=2.0.1 + - platformdirs + - build ; extra == 'dev' + - twine ; extra == 'dev' + - sphinx ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - xraydb[dev,doc,test] ; extra == 'all' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl + name: pip + version: 26.1.1 + sha256: 99cb1c2899893b075ff56e4ed0af55669a955b49ad7fb8d8603ecdaf4ed653fb + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl + name: fonttools + version: 4.62.1 + sha256: c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz + name: python-bidi + version: 0.6.9 + sha256: 001c1769893fd859216b0dc39dd4679c7260bf292c3637b727a928402a254322 requires_dist: - - locket - - toolz - - numpy>=1.20.0 ; extra == 'complete' - - pandas>=1.3 ; extra == 'complete' - - pyzmq ; extra == 'complete' - - blosc ; extra == 'complete' + - nox ; extra == 'dev' + - pytest ; extra == 'dev' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - sha256: 6eaee417d33f298db79bc7185ab1208604c0e6cf51dade34cd513c6f9db9c6f3 - md5: 11adc78451c998c0fd162584abfa3559 - depends: - - python >=3.10 - license: MPL-2.0 - license_family: MOZILLA - purls: - - pkg:pypi/pathspec?source=compressed-mapping - size: 56559 - timestamp: 1777271601895 -- pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl - name: periodictable - version: 2.1.0 - sha256: e9155d2bf5ac10050abeff2f99096d4f04312c0c8a6bb432e28744367c5064b3 +- pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + name: spdx-headers + version: 1.5.1 + sha256: 73bcb1ed087824b55ccaa497d03d8f0f0b0eaf30e5f0f7d5bbd29d2c4fe78fcf requires_dist: - - pyparsing>=3.0.0 - - numpy - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a - md5: d0d408b1f18883a944376da5cf8101ea - depends: - - ptyprocess >=0.5 - - python >=3.9 - license: ISC - purls: - - pkg:pypi/pexpect?source=hash-mapping - size: 53561 - timestamp: 1733302019362 + - chardet>=5.2.0 + - requests>=2.32.3 + - black>=23.0.0 ; extra == 'dev' + - build>=0.10.0 ; extra == 'dev' + - hatch>=1.9.0 ; extra == 'dev' + - isort>=5.12.0 ; extra == 'dev' + - mypy>=1.0.0 ; extra == 'dev' + - pre-commit>=4.3.0 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'dev' + - pytest>=7.0.0 ; extra == 'dev' + - ruff>=0.5.0 ; extra == 'dev' + - twine>=4.0.0 ; extra == 'dev' + - types-requests>=2.31.0.6 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'test' + - pytest-mock>=3.10.0 ; extra == 'test' + - pytest>=7.0.0 ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl + name: python-bidi + version: 0.6.9 + sha256: c3554a3cb9b95e503bc348a8c461b330bf1812c500f51bc9bbd789544fc4a8aa + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + name: widgetsnbextension + version: 4.0.15 + sha256: 8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl name: pillow version: 12.2.0 @@ -9576,138 +9828,199 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl - name: pillow - version: 12.2.0 - sha256: 71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65 +- pypi: https://files.pythonhosted.org/packages/3f/d0/7b958df957e4827837b590944008f0b28078f552b451f7407b4b3d54f574/asciichartpy-1.5.25-py2.py3-none-any.whl + name: asciichartpy + version: 1.5.25 + sha256: 33c417a3c8ef7d0a11b98eb9ea6dd9b2c1b17559e539b207a17d26d4302d0258 requires_dist: - - furo ; extra == 'docs' - - olefile ; extra == 'docs' - - sphinx>=8.2 ; extra == 'docs' - - sphinx-autobuild ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - sphinxext-opengraph ; extra == 'docs' - - olefile ; extra == 'fpx' - - olefile ; extra == 'mic' - - arro3-compute ; extra == 'test-arrow' - - arro3-core ; extra == 'test-arrow' - - nanoarrow ; extra == 'test-arrow' - - pyarrow ; extra == 'test-arrow' - - check-manifest ; extra == 'tests' - - coverage>=7.4.2 ; extra == 'tests' - - defusedxml ; extra == 'tests' - - markdown2 ; extra == 'tests' - - olefile ; extra == 'tests' - - packaging ; extra == 'tests' - - pyroma>=5 ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-timeout ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - trove-classifiers>=2024.10.12 ; extra == 'tests' - - defusedxml ; extra == 'xmp' + - setuptools + - flake8 ; extra == 'qa' +- pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl + name: typer + version: 0.25.1 + sha256: 75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 + requires_dist: + - click>=8.2.1 + - shellingham>=1.3.0 + - rich>=13.8.0 + - annotated-doc>=0.0.2 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: pillow - version: 12.2.0 - sha256: eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 +- pypi: https://files.pythonhosted.org/packages/42/d9/27b13bc9419bf5dae02905b348f16ca827646cd76244ddd326f1a8139a6a/cyclebane-24.10.0-py3-none-any.whl + name: cyclebane + version: 24.10.0 + sha256: 902dd318667e4a222afc270cc5bc72c67d5d6047d2e0e1c36018885fb80f5e5d requires_dist: - - furo ; extra == 'docs' - - olefile ; extra == 'docs' - - sphinx>=8.2 ; extra == 'docs' - - sphinx-autobuild ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - sphinxext-opengraph ; extra == 'docs' - - olefile ; extra == 'fpx' - - olefile ; extra == 'mic' - - arro3-compute ; extra == 'test-arrow' - - arro3-core ; extra == 'test-arrow' - - nanoarrow ; extra == 'test-arrow' - - pyarrow ; extra == 'test-arrow' - - check-manifest ; extra == 'tests' - - coverage>=7.4.2 ; extra == 'tests' - - defusedxml ; extra == 'tests' - - markdown2 ; extra == 'tests' - - olefile ; extra == 'tests' - - packaging ; extra == 'tests' - - pyroma>=5 ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-timeout ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - trove-classifiers>=2024.10.12 ; extra == 'tests' - - defusedxml ; extra == 'xmp' + - networkx requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl - name: pillow - version: 12.2.0 - sha256: 6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60 +- pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl + name: pycairo + version: 1.29.0 + sha256: 91114e4b3fbf4287c2b0788f83e1f566ce031bda49cf1c3c3c19c3e986e95c38 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl + name: mpmath + version: 1.3.0 + sha256: a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c requires_dist: - - furo ; extra == 'docs' - - olefile ; extra == 'docs' - - sphinx>=8.2 ; extra == 'docs' - - sphinx-autobuild ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - sphinxext-opengraph ; extra == 'docs' - - olefile ; extra == 'fpx' - - olefile ; extra == 'mic' - - arro3-compute ; extra == 'test-arrow' - - arro3-core ; extra == 'test-arrow' - - nanoarrow ; extra == 'test-arrow' - - pyarrow ; extra == 'test-arrow' - - check-manifest ; extra == 'tests' - - coverage>=7.4.2 ; extra == 'tests' - - defusedxml ; extra == 'tests' - - markdown2 ; extra == 'tests' - - olefile ; extra == 'tests' - - packaging ; extra == 'tests' - - pyroma>=5 ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-timeout ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - trove-classifiers>=2024.10.12 ; extra == 'tests' - - defusedxml ; extra == 'xmp' + - pytest>=4.6 ; extra == 'develop' + - pycodestyle ; extra == 'develop' + - pytest-cov ; extra == 'develop' + - codecov ; extra == 'develop' + - wheel ; extra == 'develop' + - sphinx ; extra == 'docs' + - gmpy2>=2.1.0a4 ; platform_python_implementation != 'PyPy' and extra == 'gmpy' + - pytest>=4.6 ; extra == 'tests' +- pypi: https://files.pythonhosted.org/packages/44/0b/0615dbedb98f5b32a35a53290fbdc6e22306968109278d7e58df82d7a9f6/numba-0.65.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: numba + version: 0.65.1 + sha256: f80ed83774b5173abd6581cd8d2165d1d38e13d2e5c8155c0c0b421784745420 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/44/0d/f494a2ec62ab56ffd44da4f236db374421fe0cd1e39d9ebc9785751eb432/periodictable-2.1.0-py3-none-any.whl + name: periodictable + version: 2.1.0 + sha256: e9155d2bf5ac10050abeff2f99096d4f04312c0c8a6bb432e28744367c5064b3 + requires_dist: + - pyparsing>=3.0.0 + - numpy + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/44/1f/227f9cb7edcd3e14ab05928f3db00e9d595c0f269c87bf35f565ce44941b/arviz-0.23.4-py3-none-any.whl + name: arviz + version: 0.23.4 + sha256: c46c7faf8a06abadc9b5b64000584062ecbc20c2298e2bd6dfba04bb01a684ca + requires_dist: + - setuptools>=60.0.0 + - matplotlib>=3.8 + - numpy>=1.26.0 + - scipy>=1.11.0 + - packaging + - pandas>=2.1.0 + - xarray>=2023.7.0 + - h5netcdf>=1.0.2 + - h5py + - typing-extensions>=4.1.0 + - xarray-einstats>=0.3 + - platformdirs + - numba ; extra == 'all' + - netcdf4 ; extra == 'all' + - bokeh>=3 ; extra == 'all' + - contourpy ; extra == 'all' + - ujson ; extra == 'all' + - dask[distributed] ; extra == 'all' + - zarr>=2.5.0,<3 ; extra == 'all' + - xarray>=2024.11.0 ; extra == 'all' + - dm-tree>=0.1.8 ; extra == 'all' + - arviz-base[h5netcdf] ; extra == 'preview' + - arviz-stats[xarray] ; extra == 'preview' + - arviz-plots ; extra == 'preview' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl + name: pandas + version: 3.0.2 + sha256: ed72cb3f45190874eb579c64fa92d9df74e98fd63e2be7f62bce5ace0ade61df + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/46/27/5799b020e4cdfb25a7c951c06a96397c135efcdc21b78d853bbd9c814c7d/llvmlite-0.47.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: llvmlite + version: 0.47.0 + sha256: ca14f02e29134e837982497959a8e2193d6035235de1cb41a9cb2bd6da4eedbb requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl - name: pillow - version: 12.2.0 - sha256: 56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f - requires_dist: - - furo ; extra == 'docs' - - olefile ; extra == 'docs' - - sphinx>=8.2 ; extra == 'docs' - - sphinx-autobuild ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - sphinxext-opengraph ; extra == 'docs' - - olefile ; extra == 'fpx' - - olefile ; extra == 'mic' - - arro3-compute ; extra == 'test-arrow' - - arro3-core ; extra == 'test-arrow' - - nanoarrow ; extra == 'test-arrow' - - pyarrow ; extra == 'test-arrow' - - check-manifest ; extra == 'tests' - - coverage>=7.4.2 ; extra == 'tests' - - defusedxml ; extra == 'tests' - - markdown2 ; extra == 'tests' - - olefile ; extra == 'tests' - - packaging ; extra == 'tests' - - pyroma>=5 ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-timeout ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - trove-classifiers>=2024.10.12 ; extra == 'tests' - - defusedxml ; extra == 'xmp' +- pypi: https://files.pythonhosted.org/packages/46/9f/4898b44e4042c60fafcb1162dfb7014f6f15b1ec19bf29cfea6bf26df90d/llvmlite-0.47.0-cp313-cp313-win_amd64.whl + name: llvmlite + version: 0.47.0 + sha256: c2e9adf8698d813a9a5efb2d4370caf344dbc1e145019851fee6a6f319ba760e requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl name: pillow version: 12.2.0 - sha256: e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176 + sha256: 71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -9726,1625 +10039,1381 @@ packages: - coverage>=7.4.2 ; extra == 'tests' - defusedxml ; extra == 'tests' - markdown2 ; extra == 'tests' - - olefile ; extra == 'tests' - - packaging ; extra == 'tests' - - pyroma>=5 ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-timeout ; extra == 'tests' - - pytest-xdist ; extra == 'tests' - - trove-classifiers>=2024.10.12 ; extra == 'tests' - - defusedxml ; extra == 'xmp' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/3a/eb/fea4d1d51c49832120f7f285d07306db3960f423a2612c6057caf3e8196f/pip-26.1.1-py3-none-any.whl - name: pip - version: 26.1.1 - sha256: 99cb1c2899893b075ff56e4ed0af55669a955b49ad7fb8d8603ecdaf4ed653fb - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/pixi-kernel-0.7.1-pyhbbac1ac_0.conda - sha256: 506c9330b8dc5ae98f4c32629fa59fa40e6bdd42a681c48d2f9554693dd01156 - md5: d57ef7cb7ad6b5d62cef8b9bdf1d400b - depends: - - ipykernel >=6 - - jupyter_client >=7 - - jupyter_server >=2.4 - - msgspec >=0.18 - - python >=3.10 - - returns >=0.23 - - tomli >=2 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pixi-kernel?source=hash-mapping - size: 39509 - timestamp: 1764156429044 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda - sha256: 8f29915c172f1f7f4f7c9391cd5dac3ebf5d13745c8b7c8006032615246345a5 - md5: 89c0b6d1793601a2a3a3f7d2d3d8b937 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/platformdirs?source=compressed-mapping - size: 25862 - timestamp: 1775741140609 -- pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - name: plopp - version: 26.4.2 - sha256: 5cab99bb0905ce08a1d1d7d82f0f64cee7d594269ec1bd01a8a361bd14ab7bff - requires_dist: - - lazy-loader>=0.4 - - matplotlib>=3.8 - - scipp>=25.8.0 ; extra == 'scipp' - - plopp[scipp] ; extra == 'all' - - ipympl>0.8.4 ; extra == 'all' - - pythreejs>=2.4.1 ; extra == 'all' - - mpltoolbox>=24.6.0 ; extra == 'all' - - ipywidgets>=8.1.0 ; extra == 'all' - - graphviz>=0.20.3 ; extra == 'all' - - plopp[scipp] ; extra == 'test' - - graphviz>=0.20.3 ; extra == 'test' - - h5py>=3.12 ; extra == 'test' - - ipympl>=0.8.4 ; extra == 'test' - - ipywidgets>=8.1.0 ; extra == 'test' - - ipykernel>=6.26,<7 ; extra == 'test' - - mpltoolbox>=24.6.0 ; extra == 'test' - - pandas>=2.2.2 ; extra == 'test' - - plotly>=5.15.0 ; extra == 'test' - - pooch>=1.5 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'test' - - pytest>=8.0 ; extra == 'test' - - pythreejs>=2.4.1 ; extra == 'test' - - scipy>=1.10.0 ; extra == 'test' - - xarray>=2024.5.0 ; extra == 'test' - - anywidget>=0.9.0 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl - name: plotly - version: 6.7.0 - sha256: ac8aca1c25c663a59b5b9140a549264a5badde2e057d79b8c772ae2920e32ff0 - requires_dist: - - narwhals>=1.15.1 - - packaging - - anywidget ; extra == 'dev' - - build ; extra == 'dev' - - colorcet ; extra == 'dev' - - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev' - - geopandas ; extra == 'dev' - - inflect ; extra == 'dev' - - jupyterlab ; extra == 'dev' - - kaleido>=1.1.0 ; extra == 'dev' - - numpy>=1.22 ; extra == 'dev' - - orjson ; extra == 'dev' - - pandas ; extra == 'dev' - - pdfrw ; extra == 'dev' - - pillow ; extra == 'dev' - - plotly-geo ; extra == 'dev' - - polars[timezone] ; extra == 'dev' - - pyarrow ; extra == 'dev' - - pyshp ; extra == 'dev' - - pytest ; extra == 'dev' - - pytz ; extra == 'dev' - - requests ; extra == 'dev' - - ruff==0.11.12 ; extra == 'dev' - - scikit-image ; extra == 'dev' - - scipy ; extra == 'dev' - - shapely ; extra == 'dev' - - statsmodels ; extra == 'dev' - - vaex ; python_full_version < '3.10' and extra == 'dev' - - xarray ; extra == 'dev' - - build ; extra == 'dev-build' - - jupyterlab ; extra == 'dev-build' - - pytest ; extra == 'dev-build' - - requests ; extra == 'dev-build' - - ruff==0.11.12 ; extra == 'dev-build' - - pytest ; extra == 'dev-core' - - requests ; extra == 'dev-core' - - ruff==0.11.12 ; extra == 'dev-core' - - anywidget ; extra == 'dev-optional' - - build ; extra == 'dev-optional' - - colorcet ; extra == 'dev-optional' - - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev-optional' - - geopandas ; extra == 'dev-optional' - - inflect ; extra == 'dev-optional' - - jupyterlab ; extra == 'dev-optional' - - kaleido>=1.1.0 ; extra == 'dev-optional' - - numpy>=1.22 ; extra == 'dev-optional' - - orjson ; extra == 'dev-optional' - - pandas ; extra == 'dev-optional' - - pdfrw ; extra == 'dev-optional' - - pillow ; extra == 'dev-optional' - - plotly-geo ; extra == 'dev-optional' - - polars[timezone] ; extra == 'dev-optional' - - pyarrow ; extra == 'dev-optional' - - pyshp ; extra == 'dev-optional' - - pytest ; extra == 'dev-optional' - - pytz ; extra == 'dev-optional' - - requests ; extra == 'dev-optional' - - ruff==0.11.12 ; extra == 'dev-optional' - - scikit-image ; extra == 'dev-optional' - - scipy ; extra == 'dev-optional' - - shapely ; extra == 'dev-optional' - - statsmodels ; extra == 'dev-optional' - - vaex ; python_full_version < '3.10' and extra == 'dev-optional' - - xarray ; extra == 'dev-optional' - - numpy>=1.22 ; extra == 'express' - - kaleido>=1.1.0 ; extra == 'kaleido' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - name: pluggy - version: 1.6.0 - sha256: e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl + name: pyhanko + version: 0.35.1 + sha256: 57c085f29d7f87334be2a5fbd38a1ca3c987f40f51aea38bde628497d6d9ef2e requires_dist: - - pre-commit ; extra == 'dev' - - tox ; extra == 'dev' - - pytest ; extra == 'testing' - - pytest-benchmark ; extra == 'testing' - - coverage ; extra == 'testing' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/plumbum-1.10.0-pyhcf101f3_0.conda - sha256: 972e0c1c9f0b1763d482e885732baef7f9a0cbe8686f5e2c6bdd88838619a59a - md5: 7fd2e38f4e608f5ebd80f871352c5495 - depends: - - python >=3.10 - - pywin32-on-windows - - paramiko - - importlib_resources - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/plumbum?source=hash-mapping - size: 103911 - timestamp: 1761911487086 -- pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl - name: ply - version: '3.11' - sha256: 096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce -- pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl - name: pooch - version: 1.9.0 - sha256: f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b + - asn1crypto>=1.5.1 + - tzlocal>=4.3 + - pyhanko-certvalidator>=0.31.1,<0.32 + - requests>=2.31.0 + - pyyaml>=6.0 + - cryptography>=48.0.0 + - lxml>=5.4.0 + - fonttools>=4.33.3 ; extra == 'opentype' + - uharfbuzz>=0.25.0,<0.55.0 ; extra == 'opentype' + - qrcode>=7.3.1 ; extra == 'qr' + - pillow>=7.2.0 ; extra == 'image-support' + - python-barcode==0.16.1 ; extra == 'image-support' + - python-pkcs11~=0.9.3 ; extra == 'pkcs11' + - aiohttp>=3.9,<3.14 ; extra == 'async-http' + - xsdata>=24.4,<27.0 ; extra == 'etsi' + - signxml>=4.2.0 ; extra == 'etsi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/4a/f3/00bb1e867fba351e2d784170955713bee200c43ea306c59f30bd7e748192/dask-2026.3.0-py3-none-any.whl + name: dask + version: 2026.3.0 + sha256: be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d requires_dist: - - platformdirs>=2.5.0 + - click>=8.1 + - cloudpickle>=3.0.0 + - fsspec>=2021.9.0 - packaging>=20.0 - - requests>=2.19.0 - - tqdm>=4.41.0,<5.0.0 ; extra == 'progress' - - paramiko>=2.7.0 ; extra == 'sftp' - - xxhash>=1.4.3 ; extra == 'xxhash' - - pytest-httpserver ; extra == 'test' - - pytest-localftpserver ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl - name: pre-commit - version: 4.6.0 - sha256: e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b - requires_dist: - - cfgv>=2.0.0 - - identify>=1.0.0 - - nodeenv>=0.11.1 - - pyyaml>=5.1 - - virtualenv>=20.10.0 + - partd>=1.4.0 + - pyyaml>=5.3.1 + - toolz>=0.12.0 + - importlib-metadata>=4.13.0 ; python_full_version < '3.12' + - numpy>=1.24 ; extra == 'array' + - dask[array] ; extra == 'dataframe' + - pandas>=2.0 ; extra == 'dataframe' + - pyarrow>=16.0 ; extra == 'dataframe' + - distributed>=2026.3.0,<2026.3.1 ; extra == 'distributed' + - bokeh>=3.1.0 ; extra == 'diagnostics' + - jinja2>=2.10.3 ; extra == 'diagnostics' + - dask[array,dataframe,diagnostics,distributed] ; extra == 'complete' + - pyarrow>=16.0 ; extra == 'complete' + - lz4>=4.3.2 ; extra == 'complete' + - pandas[test] ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - pre-commit ; extra == 'test' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl - name: prettytable - version: 3.17.0 - sha256: aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 +- pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 requires_dist: - - wcwidth - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-lazy-fixtures ; extra == 'tests' + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl + name: matplotlib + version: 3.10.9 + sha256: dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - sha256: 4d7ec90d4f9c1f3b4a50623fefe4ebba69f651b102b373f7c0e9dbbfa43d495c - md5: a11ab1f31af799dd93c3a39881528884 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/prometheus-client?source=compressed-mapping - size: 57113 - timestamp: 1775771465170 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda - sha256: ebc1bb62ac612af6d40667da266ff723662394c0ca78935340a5b5c14831227b - md5: d17ae9db4dc594267181bd199bf9a551 - depends: - - python >=3.9 - - wcwidth - constrains: - - prompt_toolkit 3.0.51 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/prompt-toolkit?source=hash-mapping - size: 271841 - timestamp: 1744724188108 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.51-hd8ed1ab_0.conda - sha256: 936189f0373836c1c77cd2d6e71ba1e583e2d3920bf6d015e96ee2d729b5e543 - md5: 1e61ab85dd7c60e5e73d853ea035dc29 - depends: - - prompt-toolkit >=3.0.51,<3.0.52.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 7182 - timestamp: 1744724189376 +- pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + name: simple-websocket + version: 1.1.0 + sha256: 4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c + requires_dist: + - wsproto + - tox ; extra == 'dev' + - flake8 ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - sphinx ; extra == 'docs' + requires_python: '>=3.6' - pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: propcache version: 0.4.1 sha256: fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - name: propcache - version: 0.4.1 - sha256: cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl - name: propcache - version: 0.4.1 - sha256: 6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e +- pypi: https://files.pythonhosted.org/packages/52/a0/c1f604538ff6db22a0690be2dc44ab59178e115f63c917794e529356ab23/h5py-3.16.0-cp311-cp311-manylinux_2_28_x86_64.whl + name: h5py + version: 3.16.0 + sha256: fb1720028d99040792bb2fb31facb8da44a6f29df7697e0b84f0d79aff2e9bd3 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: spglib + version: 2.6.0 + sha256: cc9d856d7cc936dc73b6b303aaf8b2fb4230a8527659373450c6e1139cbb2a5c + requires_dist: + - numpy>=1.20,<3 + - importlib-resources ; python_full_version < '3.10' + - typing-extensions>=4.9.0 ; python_full_version < '3.13' + - pytest ; extra == 'test' + - pyyaml ; extra == 'test' + - sphinx>=7.0 ; extra == 'docs' + - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - myst-parser>=2.0 ; extra == 'docs' + - linkify-it-py ; extra == 'docs' + - sphinx-tippy ; extra == 'docs' + - spglib[test] ; extra == 'test-cov' + - pytest-cov ; extra == 'test-cov' + - spglib[test] ; extra == 'test-benchmark' + - pytest-benchmark ; extra == 'test-benchmark' + - spglib[test] ; extra == 'dev' + - pre-commit ; extra == 'dev' + - spglib[docs] ; extra == 'doc' + - spglib[test] ; extra == 'testing' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: propcache - version: 0.4.1 - sha256: d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f +- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + name: pluggy + version: 1.6.0 + sha256: e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + requires_dist: + - pre-commit ; extra == 'dev' + - tox ; extra == 'dev' + - pytest ; extra == 'testing' + - pytest-benchmark ; extra == 'testing' + - coverage ; extra == 'testing' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl - name: propcache - version: 0.4.1 - sha256: 364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 +- pypi: https://files.pythonhosted.org/packages/55/5f/25bdec773905bff0ff6cf35ca73b17bd05593b4f87bd8c5fa43705f7167d/chardet-7.4.3-cp313-cp313-macosx_11_0_arm64.whl + name: chardet + version: 7.4.3 + sha256: 4fbff1907925b0c5a1064cffb5e040cd5e338585c9c552625f30de6bc2f3107a + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz + name: svglib + version: 1.5.1 + sha256: 3ae765d3a9409ee60c0fb4d24c2deb6a80617aa927054f5bcd7fc98f0695e587 + requires_dist: + - reportlab + - lxml + - tinycss2>=0.6.0 + - cssselect2>=0.2.0 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + name: ipywidgets + version: 8.1.8 + sha256: ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e + requires_dist: + - comm>=0.1.3 + - ipython>=6.1.0 + - traitlets>=4.3.1 + - widgetsnbextension~=4.0.14 + - jupyterlab-widgets~=3.0.15 + - jsonschema ; extra == 'test' + - ipykernel ; extra == 'test' + - pytest>=3.6.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytz ; extra == 'test' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl + name: numpy + version: 2.4.4 + sha256: 5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: python-bidi + version: 0.6.9 + sha256: 6cf6941062f0589291a396b3d81636b7e35a99105098bc147c48e077c0fb4b45 + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - name: propcache - version: 0.4.1 - sha256: 381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e +- pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda - sha256: 8d9325af538a8f56013e42bbb91a4dc6935aece34476e20bafacf6007b571e86 - md5: 2ed8f6fe8b51d8e19f7621941f7bb95f - depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 231786 - timestamp: 1769678156460 -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda - sha256: f19fd682d874689dfde20bf46d7ec1a28084af34583e0405685981363af47c91 - md5: 25fe6e02c2083497b3239e21b49d8093 - depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 228663 - timestamp: 1769678153829 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda - sha256: 2b774e8f4ccaac8783d1908f281e4bb20b7036d6708dc913ee7811b070f5b4b5 - md5: 7cff50265141513c960f00ba586780ea - depends: - - python - - python 3.11.* *_cpython - - __osx >=11.0 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 245203 - timestamp: 1769678306347 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda - sha256: 1d2a6039fb71d61134b1d6816202529f2f6286c83b59bc1491fd288f5c08046e - md5: ba2d89e51a855963c767648f44c03871 - depends: - - python - - __osx >=11.0 - - python 3.13.* *_cp313 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 242596 - timestamp: 1769678288893 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda - sha256: 32da17824abadd1f5b46faedfa4964c7b1817b11887c2e8bb4e48628da51b93a - md5: fd968cdacc7967efd0ff5ef1805b812c - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 249478 - timestamp: 1769678166841 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda - sha256: 3ec3373748f83069bef93b540de416e637ee30231b222d5df8f712e93f2f9195 - md5: 761b299a6289c77459defea3563f8fc0 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 246062 - timestamp: 1769678176886 -- conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - sha256: a7713dfe30faf17508ec359e0bc7e0983f5d94682492469bd462cdaae9c64d83 - md5: 7d9daffbb8d8e0af0f769dbbcd173a54 - depends: - - python >=3.9 - license: ISC - purls: - - pkg:pypi/ptyprocess?source=hash-mapping - size: 19457 - timestamp: 1733302371990 -- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 - md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pure-eval?source=hash-mapping - size: 16668 - timestamp: 1733569518868 -- pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - name: py - version: 1.11.0 - sha256: 607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/25/7d/cea3531f77df694ac7f169378250d85f19f69b09a5f4fa45f650837ae7cc/py3dmol-2.5.4-py2.py3-none-any.whl - name: py3dmol - version: 2.5.4 - sha256: 32806726b5310524a2b5bfee320737f7feef635cafc945c991062806daa9e43a +- pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + name: mkdocs-material-extensions + version: 1.3.1 + sha256: adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl + name: scipy + version: 1.17.1 + sha256: 7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d requires_dist: - - ipython ; extra == 'ipython' -- pypi: https://files.pythonhosted.org/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl - name: pycairo - version: 1.29.0 - sha256: 91114e4b3fbf4287c2b0788f83e1f566ce031bda49cf1c3c3c19c3e986e95c38 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl - name: pycairo - version: 1.29.0 - sha256: 3391532db03f9601c1cee9ebfa15b7d1db183c6020f3e75c1348cee16825934f - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pycifrw - version: 5.0.1 - sha256: 65a90ee34e46e6be20834493382585277d12daaa8d1a145cb158c163b3d9fc1c + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + name: mpld3 + version: 0.5.12 + sha256: bea31799a4041029a906f53f2662bbf1c49903e0c0bc712b412354158ec7cf54 requires_dist: - - prettytable - - ply - - numpy -- pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl - name: pycifrw - version: 5.0.1 - sha256: e9ad2fdb4fca6398ed5ae50c19908bf6238434893b68d0125bda79a54a03d708 + - jinja2 + - matplotlib +- pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl + name: scippnexus + version: 26.1.1 + sha256: 899a0a5e71291b7809d902c17b6c74addf5a805397eabcec557491ff74eead12 requires_dist: - - prettytable - - ply - - numpy -- pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl + - scipp>=24.2.0 + - scipy>=1.10.0 + - h5py>=3.12 + - pytest>=7.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5c/a5/a8c7562ec39f2647245b52ea4aeb13b5b125b3f48c0c152e9ebce7047a0a/pycifrw-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: pycifrw version: 5.0.1 - sha256: 8632df76b99932408ab432e09b30aa9a6c390df884a5f34f1e1f76201e625156 + sha256: 65a90ee34e46e6be20834493382585277d12daaa8d1a145cb158c163b3d9fc1c requires_dist: - prettytable - ply - numpy -- pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz - name: pycifstar - version: 0.3.0 - sha256: 5892fdf16c83372ee5f32557127d5f36e14b0bbe520883a4e2e70365382f70ed -- pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - name: pycodestyle - version: 2.14.0 - sha256: dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d +- pypi: https://files.pythonhosted.org/packages/5d/a6/e9b8f8a3e99602792b01fa7d0a731737615ab56d8bfd0b52935a0ef88b85/chardet-7.4.3-cp311-cp311-win_amd64.whl + name: chardet + version: 7.4.3 + sha256: ccc1f83ab4bcfb901cf39e0c4ba6bc6e726fc6264735f10e24ceb5cb47387578 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 - md5: 12c566707c80111f9799308d9e265aef - depends: - - python >=3.9 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pycparser?source=hash-mapping - size: 110100 - timestamp: 1733195786147 -- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda - sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f - md5: 729843edafc0899b3348bd3f19525b9d - depends: - - typing-inspection >=0.4.2 - - typing_extensions >=4.14.1 - - python >=3.10 - - annotated-types >=0.6.0 - - pydantic-core ==2.46.4 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic?source=compressed-mapping - size: 346511 - timestamp: 1778103405862 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py311h902ca64_0.conda - sha256: ac3faa31154a85f4b1a4618957b4a06623ff2c6a85f8eac20efe9dbac5757d91 - md5: b6cfa054aec29586d383f9e666bd0e9a - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.11.* *_cp311 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1884122 - timestamp: 1778084220486 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py313h843e2db_0.conda - sha256: d6705962afa2655cc22edcd075ce1f7e67c4407c005137d6d63c0dc5eaa76f47 - md5: ef0f9efec6ec28b17e22f787c7672c67 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.13.* *_cp313 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1893749 - timestamp: 1778084222642 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py311hf7c400d_0.conda - sha256: 194e8872dcda301703c8f1427e480fee6421e3901803ffc863b68eb886372eaf - md5: 80d6864b30e0697b652a9bd580b2d351 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - __osx >=11.0 - - python 3.11.* *_cpython - - python_abi 3.11.* *_cp311 - constrains: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1730463 - timestamp: 1778084304998 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.46.4-py313h212e517_0.conda - sha256: 5bcc20f2c21d8a20d8f2821caf31d8c0ef2fa3bcdaf7a9bdce62e37be819f1d7 - md5: 32bb0d4dbb1be2064c06248a1190aa96 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - python 3.13.* *_cp313 - - __osx >=11.0 - - python_abi 3.13.* *_cp313 - constrains: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1720475 - timestamp: 1778084300413 -- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py311hf51aa87_0.conda - sha256: 4cf860418a6a1a678bcc23bc29a83f4f0916682fd6ab1ff209b4e5ee3dc5e15f - md5: 85efdb748cbec9210e718c4a8860749c - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1898998 - timestamp: 1778084255268 -- conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.46.4-py313hfbe8231_0.conda - sha256: 6466b7e441adb71e29308de2a87c9787d5d0100601ede2d02ed4f85c251699d6 - md5: 9981bc46be6341306a5473b290b2f366 - depends: - - python - - typing-extensions >=4.6.0,!=4.7.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pydantic-core?source=hash-mapping - size: 1888029 - timestamp: 1778084253466 -- pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl - name: pydoclint - version: 0.8.3 - sha256: 5fc9b82d0d515afce0908cb70e8ff695a68b19042785c248c4f227ad66b4a164 +- pypi: https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl + name: pandas + version: 3.0.2 + sha256: 07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl + name: lxml + version: 6.1.0 + sha256: cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db requires_dist: - - click>=8.1.0 - - docstring-parser-fork>=0.0.12 - - tomli>=2.0.1 ; python_full_version < '3.11' - - flake8>=4 ; extra == 'flake8' + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl + name: scipp + version: 26.3.1 + sha256: 67d275fc83b062053df9aa7ce3af4d2205109c2bc3ab22467bcd73ceb0a83df2 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/61/2b/e260d50e64690d2a9e405d52ccd18a63c286c5088937dd0107cb23eb3195/diffpy_utils-3.7.2-py3-none-any.whl + name: diffpy-utils + version: 3.7.2 + sha256: 6100600736791a8e4638e3dd476704f4dabe3cab75bcb5c60c83c16a2032519a + requires_dist: + - numpy + - xraydb + - scipy + requires_python: '>=3.10,<3.15' +- pypi: https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl + name: matplotlib + version: 3.10.9 + sha256: b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 - md5: 16c18772b340887160c79a6acc022db0 - depends: - - python >=3.10 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/pygments?source=compressed-mapping - size: 893031 - timestamp: 1774796815820 -- pypi: https://files.pythonhosted.org/packages/4a/1a/bea014b55c45c98c63dffd34d2dd01eed0a73ce5b175bd7b1ba798d13558/pyhanko-0.35.1-py3-none-any.whl - name: pyhanko - version: 0.35.1 - sha256: 57c085f29d7f87334be2a5fbd38a1ca3c987f40f51aea38bde628497d6d9ef2e +- pypi: https://files.pythonhosted.org/packages/64/2e/ba6b404a8a0e7c954cdf0fdd2b21723dc41def60f16b69b9b1cbb2e22d91/crysfml-0.6.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: crysfml + version: 0.6.2 + sha256: 734e2180b2c427e77cc9cf9cee4a3651ad563adab28dfe79051f004489f8546c requires_dist: - - asn1crypto>=1.5.1 - - tzlocal>=4.3 - - pyhanko-certvalidator>=0.31.1,<0.32 - - requests>=2.31.0 - - pyyaml>=6.0 - - cryptography>=48.0.0 - - lxml>=5.4.0 - - fonttools>=4.33.3 ; extra == 'opentype' - - uharfbuzz>=0.25.0,<0.55.0 ; extra == 'opentype' - - qrcode>=7.3.1 ; extra == 'qr' - - pillow>=7.2.0 ; extra == 'image-support' - - python-barcode==0.16.1 ; extra == 'image-support' - - python-pkcs11~=0.9.3 ; extra == 'pkcs11' - - aiohttp>=3.9,<3.14 ; extra == 'async-http' - - xsdata>=24.4,<27.0 ; extra == 'etsi' - - signxml>=4.2.0 ; extra == 'etsi' + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/64/a8/c09fbe44b12fa919c5bfe0afb71e60d1231a7dc93405e54c30496c57c9d3/arviz-1.1.0-py3-none-any.whl + name: arviz + version: 1.1.0 + sha256: 87ebd21ce052f30d21f932b4166fc31b91c0bc7443f8da7fed3518b342267010 + requires_dist: + - arviz-base>=1.1.0,<1.2.0 + - arviz-stats[xarray]>=1.1.0,<1.2.0 + - arviz-plots>=1.1.0,<1.2.0 + - arviz-plots[bokeh] ; extra == 'bokeh' + - build ; extra == 'check' + - pre-commit ; extra == 'check' + - h5netcdf ; extra == 'doc' + - h5py ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - matplotlib ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - pydata-sphinx-theme>=0.13 ; extra == 'doc' + - sphinx>=5 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-notfound-page ; extra == 'doc' + - sphinxcontrib-youtube ; extra == 'doc' + - sphinx-togglebutton ; extra == 'doc' + - sphobjinv ; extra == 'doc' + - arviz-base[h5netcdf] ; extra == 'h5netcdf' + - arviz-plots[matplotlib] ; extra == 'matplotlib' + - arviz-base[netcdf4] ; extra == 'netcdf4' + - arviz-plots[plotly] ; extra == 'plotly' + - pytest ; extra == 'test' + - arviz-base[zarr] ; extra == 'zarr' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl + name: coverage + version: 7.13.5 + sha256: 631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl - name: pyhanko-certvalidator - version: 0.31.1 - sha256: 0aabe25b536ed555f3b18e5eb2c62ff46adeff9d15e27f0c9d5d81952d956f45 +- pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: yarl + version: 1.23.0 + sha256: 34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 requires_dist: - - asn1crypto>=1.5.1 - - oscrypto>=1.1.0 - - cryptography>=48.0.0 - - uritools>=3.0.1 - - requests>=2.31.0 - - aiohttp>=3.9,<3.14 ; extra == 'async-http' + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: pillow + version: 12.2.0 + sha256: eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl + name: pillow + version: 12.2.0 + sha256: 6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/69/d1/705e6c19b437a4105bf3b9ae7945fcfc3ad2abb73d14bae0a3f2d58b305b/arviz_base-1.1.0-py3-none-any.whl + name: arviz-base + version: 1.1.0 + sha256: 4f97016f697751038f45d144331a1830c921f0ebc2739d5df343120fba453e83 + requires_dist: + - numpy>=2 + - xarray>=2024.11.0 + - typing-extensions>=3.10 + - lazy-loader>=0.4 + - build ; extra == 'check' + - pre-commit ; extra == 'check' + - docstub==0.4 ; extra == 'check' + - mypy ; extra == 'check' + - pre-commit ; extra == 'ci' + - cloudpickle ; extra == 'ci' + - sphinx-book-theme ; extra == 'doc' + - myst-parser[linkify] ; extra == 'doc' + - myst-nb ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - numpydoc ; extra == 'doc' + - sphinx>=5 ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - jupyter-sphinx ; extra == 'doc' + - h5netcdf[h5py] ; extra == 'doc' + - h5netcdf[h5py] ; extra == 'h5netcdf' + - netcdf4 ; extra == 'netcdf4' + - xarray!=2025.8.0 ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - scipy ; extra == 'test' + - zarr ; extra == 'zarr' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl + name: rlpycairo + version: 0.4.0 + sha256: 3ce83825d5761c03bc3571c7db12a336ad51417e63189e3512d11b8922576aa9 + requires_dist: + - pycairo>=1.20.0 + - freetype-py>=2.3 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/6c/25/4f103d1bedb3593718713b3f743df7b3ff3fc68d36d6666c30265ef59c8a/ase-3.28.0-py3-none-any.whl + name: ase + version: 3.28.0 + sha256: 0e24056302d7307b7247f90de281de15e3031c14cf400bedb1116c3b0d0e50b8 + requires_dist: + - numpy>=1.21.6 + - scipy>=1.8.1 + - matplotlib>=3.5.2 + - sphinx ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinxcontrib-video ; extra == 'docs' + - sphinx-gallery ; extra == 'docs' + - pillow ; extra == 'docs' + - pytest>=7.4.0 ; extra == 'test' + - pytest-xdist>=3.2.0 ; extra == 'test' + - spglib>=1.9 ; extra == 'spglib' + - mypy ; extra == 'lint' + - ruff ; extra == 'lint' + - types-docutils ; extra == 'lint' + - types-pymysql ; extra == 'lint' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl - name: pymdown-extensions - version: 10.21.2 - sha256: 5c0fd2a2bea14eb39af8ff284f1066d898ab2187d81b889b75d46d4348c01638 +- pypi: https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl + name: html5lib + version: '1.1' + sha256: 0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d requires_dist: - - markdown>=3.6 - - pyyaml - - pygments>=2.19.1 ; extra == 'extra' + - six>=1.9 + - webencodings + - genshi ; extra == 'all' + - chardet>=2.2 ; extra == 'all' + - lxml ; platform_python_implementation == 'CPython' and extra == 'all' + - chardet>=2.2 ; extra == 'chardet' + - genshi ; extra == 'genshi' + - lxml ; platform_python_implementation == 'CPython' and extra == 'lxml' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl + name: svglib + version: 1.6.0 + sha256: 9aea8e2e81cbbf9c844460e4c7dc90e0a06aea7983bc201975ccd279d7b2d194 + requires_dist: + - cssselect2>=0.2.0 + - lxml>=6.0.0 + - reportlab>=4.4.3 + - rlpycairo>=0.4.0 + - tinycss2>=0.6.0 + - mypy>=1.18.1 ; extra == 'dev' + - pre-commit>=4.3.0 ; extra == 'dev' + - pytest-cov>=7.0.0 ; extra == 'dev' + - pytest-runner>=6.0.1 ; extra == 'dev' + - pytest>=8.3.5 ; extra == 'dev' + - ruff>=0.13.0 ; extra == 'dev' + - tox>=4.30.2 ; extra == 'dev' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py311hdf6b40b_1.conda - sha256: 4b89f502dc58df0abb27d4677ca4b0ef5230f5c28e24b80eef3dc0c9c968e225 - md5: fb7e00fed4fddee97e6cf0bd3ae9a27e - depends: - - __glibc >=2.17,<3.0.a0 - - cffi >=1.4.1 - - libgcc >=14 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - six - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1151915 - timestamp: 1772171237221 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.6.2-py313h5008379_1.conda - sha256: 51e80a7bef95025ad47a92acb69ee0e78f01e107655c86fe76abcde2ac688166 - md5: c4426edfc5514a2c9be6871557bce52b - depends: - - __glibc >=2.17,<3.0.a0 - - cffi >=1.4.1 - - libgcc >=14 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - six - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1191901 - timestamp: 1772171244923 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py311h38a6bc0_1.conda - sha256: 503b3a2543577f2fb70ddc44113a4da7ecdfdfb2bf51ecd1203adcb93e7257df - md5: 64d4dd58b1eb87d7e6ba084c7dc9259b - depends: - - __osx >=11.0 - - cffi >=1.4.1 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - - six - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1188895 - timestamp: 1772171487639 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pynacl-1.6.2-py313h6940bce_1.conda - sha256: ef6ab85953ebf81b3b0c6d0b6377eb1a318b07823e76d2c8e850365e60d9ca5c - md5: fca94b9ddea6d5c63ccb6b5ad6d8e232 - depends: - - __osx >=11.0 - - cffi >=1.4.1 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - - six - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1192924 - timestamp: 1772171603602 -- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py311hcd7b28f_1.conda - sha256: cd35ad681895b45f578bac8fd8dafc87116c2db42489dda9bef76ff3518bbc73 - md5: e2197089006b3cda7e03c7a51fa7050e - depends: - - cffi >=1.4.1 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - six - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1147862 - timestamp: 1772171327674 -- conda: https://conda.anaconda.org/conda-forge/win-64/pynacl-1.6.2-py313hed4ef92_1.conda - sha256: 0960e727d0bd70e07bca0c049c4c4afa0b41bcea050135db49f54c1c0c02ed7f - md5: 99b7617a643bed6a403fc908c1e167f0 - depends: - - cffi >=1.4.1 - - libsodium >=1.0.21,<1.0.22.0a0 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - six - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/pynacl?source=hash-mapping - size: 1186552 - timestamp: 1772171311072 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py311hce6e4fa_0.conda - sha256: f6dced0ea4f220abc1278f6217e22ca1c631f6154dd086b0a7a2866589d6b78c - md5: 812e22c5c7859e719ec225ece0c6f2c1 - depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - - setuptools - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyobjc-core?source=hash-mapping - size: 481434 - timestamp: 1763151508974 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-12.1-py313h40b429f_0.conda - sha256: 307ca29ebf2317bd2561639b1ee0290fd8c03c3450fa302b9f9437d8df6a5280 - md5: 31a0a72f3466682d0ea2ebcbd7d319b8 - depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - - setuptools - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyobjc-core?source=hash-mapping - size: 481508 - timestamp: 1763152124940 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py311h9049b8e_0.conda - sha256: 67e209a5e9ebaf08aa36e2a4b9139ff91a7ecee7c17408d0a3a1ea1dc3a67681 - md5: b215a767b5ef6f16347cacebc409e66b - depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - pyobjc-core 12.1.* - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping - size: 383445 - timestamp: 1763160541362 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-framework-cocoa-12.1-py313hcc5defa_0.conda - sha256: 194e188d8119befc952d04157079733e2041a7a502d50340ddde632658799fdc - md5: a6d28c8fc266a3d3c3dae183e25c4d31 - depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - pyobjc-core 12.1.* - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyobjc-framework-cocoa?source=hash-mapping - size: 376136 - timestamp: 1763160678792 -- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - name: pyparsing - version: 3.3.2 - sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d +- pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl + name: scipy + version: 1.17.1 + sha256: a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/6e/7d/77752d819ede528c664ecf4de974b17b049e054a14537b74b53c8568014f/arabic_reshaper-3.0.1-py3-none-any.whl + name: arabic-reshaper + version: 3.0.1 + sha256: 41c5adc2420f85758eada7e880251c4b6a2adbd83377bd27e5d4eba71f648bc7 requires_dist: - - railroad-diagrams ; extra == 'diagrams' - - jinja2 ; extra == 'diagrams' + - fonttools>=4.0 ; extra == 'with-fonttools' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl + name: mkdocstrings + version: 1.0.4 + sha256: 63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b + requires_dist: + - jinja2>=3.1 + - markdown>=3.6 + - markupsafe>=1.1 + - mkdocs>=1.6 + - mkdocs-autorefs>=1.4 + - pymdown-extensions>=6.3 + - mkdocstrings-crystal>=0.3.4 ; extra == 'crystal' + - mkdocstrings-python-legacy>=0.2.1 ; extra == 'python-legacy' + - mkdocstrings-python>=1.16.2 ; extra == 'python' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0c/d6/1d5c60cc17bbdf37c1552d9c03862fc6d32c5836732a0415b2d637edc2d0/pypdf-6.10.2-py3-none-any.whl - name: pypdf - version: 6.10.2 - sha256: aa53be9826655b51c96741e5d7983ca224d898ac0a77896e64636810517624aa +- pypi: https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl + name: pillow + version: 12.2.0 + sha256: 56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f requires_dist: - - typing-extensions>=4.0 ; python_full_version < '3.11' - - cryptography ; extra == 'crypto' - - pycryptodome ; extra == 'cryptodome' - - flit ; extra == 'dev' - - pip-tools ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-socket ; extra == 'dev' - - pytest-timeout ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - wheel ; extra == 'dev' - - myst-parser ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - cryptography ; extra == 'full' - - pillow>=8.0.0 ; extra == 'full' - - pillow>=8.0.0 ; extra == 'image' + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl + name: partd + version: 1.4.2 + sha256: 978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f + requires_dist: + - locket + - toolz + - numpy>=1.20.0 ; extra == 'complete' + - pandas>=1.3 ; extra == 'complete' + - pyzmq ; extra == 'complete' + - blosc ; extra == 'complete' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - name: pyproject-hooks - version: 1.2.0 - sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca - md5: e2fd202833c4a981ce8a65974fe4abd1 - depends: - - __win - - python >=3.9 - - win_inet_pton - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pysocks?source=hash-mapping - size: 21784 - timestamp: 1733217448189 -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 - md5: 461219d1a5bd61342293efa2c0c90eac - depends: - - __unix - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pysocks?source=hash-mapping - size: 21085 - timestamp: 1733217331982 -- pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - name: pytest - version: 9.0.3 - sha256: 2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 +- pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + name: msgpack + version: 1.1.2 + sha256: a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl + name: mike + version: 2.2.0 + sha256: e1f4981c1152eec7c2490a3401142292cc47d686194188416db2648fdfe1d040 requires_dist: - - colorama>=0.4 ; sys_platform == 'win32' - - exceptiongroup>=1 ; python_full_version < '3.11' - - iniconfig>=1.0.1 - - packaging>=22 - - pluggy>=1.5,<2 - - pygments>=2.7.2 - - tomli>=1 ; python_full_version < '3.11' - - argcomplete ; extra == 'dev' - - attrs>=19.2 ; extra == 'dev' - - hypothesis>=3.56 ; extra == 'dev' - - mock ; extra == 'dev' - - requests ; extra == 'dev' + - jinja2>=2.7 + - mkdocs~=1.0 + - pyparsing>=3.0 + - pyyaml>=5.1 + - pyyaml-env-tag + - verspec + - importlib-metadata ; python_full_version < '3.10' + - importlib-resources ; python_full_version < '3.10' + - coverage ; extra == 'dev' + - flake8-quotes ; extra == 'dev' + - flake8>=3.0 ; extra == 'dev' + - shtab ; extra == 'dev' + - coverage ; extra == 'test' + - flake8-quotes ; extra == 'test' + - flake8>=3.0 ; extra == 'test' + - shtab ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/77/6f/4615353e016799f80fa52ccb270a843c413b22361fadda2589b2922fb9b0/llvmlite-0.47.0-cp313-cp313-macosx_12_0_arm64.whl + name: llvmlite + version: 0.47.0 + sha256: a3c6a735d4e1041808434f9d440faa3d78d9b4af2ee64d05a66f351883b6ceec + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/78/3c/2a612b95ddbb9a6bdcb47b7a93c4884f74c6ff22356b2f7b213b16e65c35/pycifstar-0.3.0.tar.gz + name: pycifstar + version: 0.3.0 + sha256: 5892fdf16c83372ee5f32557127d5f36e14b0bbe520883a4e2e70365382f70ed +- pypi: https://files.pythonhosted.org/packages/79/37/14a4579049c1eb673afd0de0cb4842982acd55b9ce2643e763db858bcea0/numba-0.65.1-cp313-cp313-macosx_12_0_arm64.whl + name: numba + version: 0.65.1 + sha256: 1735c15c1134a5108b4d6a5c77fc0947924ea066a738dc09a52008c13df9cad3 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: 935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: matplotlib + version: 3.10.9 + sha256: 8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl + name: scipp + version: 26.3.1 + sha256: 8dfe8adedb5cba05acaaea15e3b6fe1820ac2f497e87c1e581ba4be9d82c53bb + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7b/67/b1944235474aac3f0b0e1b232ce49547f9f9461ca4b943df1b88da5d3f1d/bumps-1.0.4-py3-none-any.whl + name: bumps + version: 1.0.4 + sha256: 78b8cfaf9fbcbf2fd77f6d4a2f8c906b0e03a794804ba6caf64d56d6f6cce4d4 + requires_dist: + - numpy + - scipy + - h5py + - dill + - cloudpickle + - matplotlib + - blinker + - aiohttp + - python-socketio + - plotly + - mpld3 + - msgpack + - uncertainties + - build ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - wheel ; extra == 'dev' - setuptools ; extra == 'dev' - - xmlschema ; extra == 'dev' + - sphinx ; extra == 'dev' + - versioningit ; extra == 'dev' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl - name: pytest-cov - version: 7.1.0 - sha256: a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 +- pypi: https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl + name: matplotlib + version: 3.10.9 + sha256: d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f requires_dist: - - coverage[toml]>=7.10.6 - - pluggy>=1.2 - - pytest>=7 - - process-tests ; extra == 'testing' - - pytest-xdist ; extra == 'testing' - - virtualenv ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - name: pytest-xdist - version: 3.8.0 - sha256: 202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.5 + sha256: 3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc requires_dist: - - execnet>=2.1 - - pytest>=7.0.0 - - filelock ; extra == 'testing' - - psutil>=3.0 ; extra == 'psutil' - - setproctitle ; extra == 'setproctitle' + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda - sha256: bf6a32c69889d38482436a786bea32276756cedf0e9805cc856ffd088e8d00f0 - md5: a5ebcefec0c12a333bcd6d7bf3bddc1f - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.4,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 - - libnsl >=2.0.1,<2.1.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libuuid >=2.41.3,<3.0a0 - - libxcrypt >=4.4.36 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.11.* *_cp311 - license: Python-2.0 - purls: [] - size: 30949404 - timestamp: 1772730362552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda - build_number: 100 - sha256: 7f77eb57648f545c1f58e10035d0d9d66b0a0efb7c4b58d3ed89ec7269afdde1 - md5: 05051be49267378d2fcd12931e319ac3 - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.5,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.52.0,<4.0a0 - - libuuid >=2.42,<3.0a0 - - libzlib >=1.3.2,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.6,<4.0a0 - - python_abi 3.13.* *_cp313 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - license: Python-2.0 - purls: [] - size: 37358322 - timestamp: 1775614712638 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.15-h8561d8f_0_cpython.conda - sha256: 9a846065863925b2562126a5c6fecd7a972e84aaa4de9e686ad3715ca506acfa - md5: 49c7d96c58b969585cf09fb01d74e08e - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.4,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.11.* *_cp311 - license: Python-2.0 - purls: [] - size: 14753109 - timestamp: 1772730203101 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.13-h20e6be0_100_cp313.conda - build_number: 100 - sha256: d0fffc5fde21d1ae350da545dfb9e115a8c53bed8a9c5761f9efd4a5581853c1 - md5: 9991a930e81d3873eba7a299ba783ec4 - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.5,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.52.0,<4.0a0 - - libzlib >=1.3.2,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.6,<4.0a0 - - python_abi 3.13.* *_cp313 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - license: Python-2.0 - purls: [] - size: 12966447 - timestamp: 1775615694085 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda - sha256: a1f1031088ce69bc99c82b95980c1f54e16cbd5c21f042e9c1ea25745a8fc813 - md5: d09dbf470b41bca48cbe6a78ba1e009b - depends: - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.4,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.5,<4.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - python_abi 3.11.* *_cp311 - license: Python-2.0 - purls: [] - size: 18416208 - timestamp: 1772728847666 -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.13-h09917c8_100_cp313.conda - build_number: 100 - sha256: b8108d7f83f71fb15fbb4a263406c2065a8990b3d7eba2cbd7a3075b9a6392ba - md5: 7065f7067762c4c2bda1912f18d16239 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.5,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.52.0,<4.0a0 - - libzlib >=1.3.2,<2.0a0 - - openssl >=3.5.6,<4.0a0 - - python_abi 3.13.* *_cp313 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Python-2.0 - purls: [] - size: 16618694 - timestamp: 1775613654892 - python_site_packages_path: Lib/site-packages -- pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: python-bidi - version: 0.6.9 - sha256: 29e40e02bf2bddec225730eb3ba9f4ca948dced9877358458b74d7a447d936ac +- pypi: https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.5.0 + sha256: 2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl + name: pre-commit + version: 4.6.0 + sha256: e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' + - cfgv>=2.0.0 + - identify>=1.0.0 + - nodeenv>=0.11.1 + - pyyaml>=5.1 + - virtualenv>=20.10.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl + name: filelock + version: 3.29.0 + sha256: 96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl + name: rich + version: 15.0.0 + sha256: 33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb + requires_dist: + - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' + - markdown-it-py>=2.2.0 + - pygments>=2.13.0,<3.0.0 + requires_python: '>=3.9.0' +- pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl + name: scippneutron + version: 26.4.1 + sha256: 3b9865ebdb7923eb25739b7cda624555d45275341000f099c1dcf371b1dd7e35 + requires_dist: + - python-dateutil>=2.8 + - email-validator>=2 + - h5py>=3.12 + - lazy-loader>=0.4 + - mpltoolbox>=24.6.0 + - numpy>=1.20 + - plopp>=26.4.1 + - pydantic>=2 + - scipp>=24.7.0 + - scippnexus>=23.11.0 + - scipy>=1.7.0 + - scipp[all]>=23.7.0 ; extra == 'all' + - pooch>=1.5 ; extra == 'all' + - hypothesis>=6.100 ; extra == 'test' + - ipympl>0.9.0 ; extra == 'test' + - ipykernel>6.30 ; extra == 'test' + - pace-neutrons>=0.3 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - psutil>=5.0 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - pytest-xdist>=3.0 ; extra == 'test' + - pythreejs>=2.4.1 ; extra == 'test' + - sciline>=25.1.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3c/0c/c73042d7ae043f4e3ff51406821ad70904249708a6bc4f0dc94f5f78ce9b/python_bidi-0.6.9.tar.gz - name: python-bidi - version: 0.6.9 - sha256: 001c1769893fd859216b0dc39dd4679c7260bf292c3637b727a928402a254322 +- pypi: https://files.pythonhosted.org/packages/83/81/bdd4bfabe70b7c9a8c0716a722ced4ebd27311afd1f4800cd405d3229c1b/pycifrw-5.0.1-cp313-cp313-macosx_11_0_arm64.whl + name: pycifrw + version: 5.0.1 + sha256: e9ad2fdb4fca6398ed5ae50c19908bf6238434893b68d0125bda79a54a03d708 requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3e/9a/a9383ff12698d5306522122e7007d9fd58f903e00a7715506e3ff5be1678/python_bidi-0.6.9-cp311-cp311-macosx_11_0_arm64.whl - name: python-bidi - version: 0.6.9 - sha256: c3554a3cb9b95e503bc348a8c461b330bf1812c500f51bc9bbd789544fc4a8aa + - prettytable + - ply + - numpy +- pypi: https://files.pythonhosted.org/packages/85/d7/9b6ac05350ab7f7d3a730ff143ff3e2cada54514117c37be37e26dc91242/docstripy-0.7.2-py3-none-any.whl + name: docstripy + version: 0.7.2 + sha256: c4ba35de6c1b1c51f7afad4a46d8953aad55dce1a490d198f7e98c8c63efefda requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5a/38/f1efc72736fb39e75802efcb5e2ba8eb02c7ee3687940047234bc607e3a5/python_bidi-0.6.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: python-bidi - version: 0.6.9 - sha256: 6cf6941062f0589291a396b3d81636b7e35a99105098bc147c48e077c0fb4b45 + - nbformat + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/87/6f/cc2b231dc78d8c3aaa674a676db190b8f8071c50134af8f8cf39b9b8e8df/pydoclint-0.8.3-py3-none-any.whl + name: pydoclint + version: 0.8.3 + sha256: 5fc9b82d0d515afce0908cb70e8ff695a68b19042785c248c4f227ad66b4a164 requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl - name: python-bidi - version: 0.6.9 - sha256: c3e4445f0fd1e2c16d3efdb28622a38f57ab4b971eb47803a334be477cee173e + - click>=8.1.0 + - docstring-parser-fork>=0.0.12 + - tomli>=2.0.1 ; python_full_version < '3.11' + - flake8>=4 ; extra == 'flake8' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.5 + sha256: e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl - name: python-bidi - version: 0.6.9 - sha256: be28092eef062fad59e7e0402bf2c1db797ccadedd866a53bbd7ddb97e42cac1 +- pypi: https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl + name: mkdocs-get-deps + version: 0.2.2 + sha256: e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650 requires_dist: - - nox ; extra == 'dev' - - pytest ; extra == 'dev' + - importlib-metadata>=4.3 ; python_full_version < '3.10' + - mergedeep>=1.3.4 + - platformdirs>=2.2.0 + - pyyaml>=5.1 requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 - md5: 5b8d21249ff20967101ffa321cab24e8 - depends: - - python >=3.9 - - six >=1.5 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/python-dateutil?source=hash-mapping - size: 233310 - timestamp: 1751104122689 -- pypi: https://files.pythonhosted.org/packages/30/d4/24d543ab8b8158b7f5a97113c831205f5c900c92c8762b1e7f44b7ea0405/python_discovery-1.3.0-py3-none-any.whl - name: python-discovery - version: 1.3.0 - sha256: 441d9ced3dfce36e113beb35ca302c71c7ef06f3c0f9c227a0b9bb3bd49b9e9f - requires_dist: - - filelock>=3.15.4 - - platformdirs>=4.3.6,<5 - - furo>=2025.12.19 ; extra == 'docs' - - sphinx-autodoc-typehints>=3.6.3 ; extra == 'docs' - - sphinx>=9.1 ; extra == 'docs' - - sphinxcontrib-mermaid>=2 ; extra == 'docs' - - covdefaults>=2.3 ; extra == 'testing' - - coverage>=7.5.4 ; extra == 'testing' - - pytest-mock>=3.14 ; extra == 'testing' - - pytest>=8.3.5 ; extra == 'testing' - - setuptools>=75.1 ; extra == 'testing' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - name: python-engineio - version: 4.13.1 - sha256: f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399 - requires_dist: - - simple-websocket>=0.10.0 - - requests>=2.21.0 ; extra == 'client' - - websocket-client>=0.54.0 ; extra == 'client' - - aiohttp>=3.11 ; extra == 'asyncio-client' - - tox ; extra == 'dev' - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - sha256: df9aa74e9e28e8d1309274648aac08ec447a92512c33f61a8de0afa9ce32ebe8 - md5: 23029aae904a2ba587daba708208012f - depends: - - python >=3.9 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/fastjsonschema?source=hash-mapping - size: 244628 - timestamp: 1755304154927 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.13-h4df99d1_100.conda - sha256: b2e51d83e5ebeb7e9fde1cde822a60e8564cc9dabd786ad853056afbf708a466 - md5: fd00e4b24ea88093c93f5c9bad27b52f - depends: - - cpython 3.13.13.* - - python_abi * *_cp313 - license: Python-2.0 - purls: [] - size: 48536 - timestamp: 1775613791711 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - sha256: 1c55116c22512cef7b01d55ae49697707f2c1fd829407183c19817e2d300fd8d - md5: 1cd2f3e885162ee1366312bd1b1677fd - depends: - - python >=3.10 - - typing_extensions - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/python-json-logger?source=compressed-mapping - size: 18969 - timestamp: 1777318679482 -- pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - name: python-socketio - version: 5.16.1 - sha256: a3eb1702e92aa2f2b5d3ba00261b61f062cce51f1cfb6900bf3ab4d1934d2d35 +- pypi: https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl + name: fonttools + version: 4.62.1 + sha256: 40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7 requires_dist: - - bidict>=0.21.0 - - python-engineio>=4.11.0 - - requests>=2.21.0 ; extra == 'client' - - websocket-client>=0.54.0 ; extra == 'client' - - aiohttp>=3.4 ; extra == 'asyncio-client' - - tox ; extra == 'dev' - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - sha256: e943f9c15a6bdba2e1b9f423ab913b3f6b02197b0ef9f8e6b7464d78b59965b9 - md5: f6ad7450fc21e00ecc23812baed6d2e4 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/tzdata?source=compressed-mapping - size: 146639 - timestamp: 1777068997932 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda - build_number: 8 - sha256: fddf123692aa4b1fc48f0471e346400d9852d96eeed77dbfdd746fa50a8ff894 - md5: 8fcb6b0e2161850556231336dae58358 - constrains: - - python 3.11.* *_cpython - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 7003 - timestamp: 1752805919375 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - build_number: 8 - sha256: 210bffe7b121e651419cb196a2a63687b087497595c9be9d20ebe97dd06060a7 - md5: 94305520c52a4aa3f6c2b1ff6008d9f8 - constrains: - - python 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 7002 - timestamp: 1752805902938 -- pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl - name: pythreejs - version: 2.4.2 - sha256: 8418807163ad91f4df53b58c4e991b26214852a1236f28f1afeaadf99d095818 + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + name: cloudpickle + version: 3.1.2 + sha256: 9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + name: nodeenv + version: 1.10.0 + sha256: 5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' +- pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/8a/06/2c1bd1ee9eee3e65b0b6395dcf960e71b11576995eae3b4ab9ec63d89bea/essreduce-26.4.1-py3-none-any.whl + name: essreduce + version: 26.4.1 + sha256: 1758a18fffca9c7c2a6fa9547cf87bf45f9d52fc3ccbdffcf7524f71bc060424 requires_dist: - - ipywidgets>=7.2.1 - - ipydatawidgets>=1.1.1 - - numpy - - traitlets - - sphinx>=1.5 ; extra == 'docs' - - nbsphinx>=0.2.13 ; extra == 'docs' - - nbsphinx-link ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - scipy ; extra == 'examples' - - matplotlib ; extra == 'examples' - - scikit-image ; extra == 'examples' - - ipywebrtc ; extra == 'examples' - - nbval ; extra == 'test' - - pytest-check-links ; extra == 'test' - - numpy>=1.14 ; extra == 'test' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py311hefeebc8_1.conda - sha256: e3ef7e0cc53111ab81b8a9dd3eabc1374d7420d4c9fce3c8631e73310203ad55 - md5: c1cfe9f5d8e278cc4d2d4c7b0126634d - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/pywin32?source=hash-mapping - size: 6729388 - timestamp: 1756487145061 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py313h40c08fc_1.conda - sha256: 87eaeb79b5961e0f216aa840bc35d5f0b9b123acffaecc4fda4de48891901f20 - md5: 1ce4f826332dca56c76a5b0cc89fb19e - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.13.* *_cp313 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/pywin32?source=hash-mapping - size: 6695114 - timestamp: 1756487139550 -- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh07e9846_2.tar.bz2 - sha256: 09803b75cccc16d8586d2f41ea890658d165f4afc359973fa1c7904a2c140eae - md5: 91733394059b880d9cc0d010c20abda0 - depends: - - python >=2.7 - - pywin32 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 5282 - timestamp: 1646866839398 -- conda: https://conda.anaconda.org/conda-forge/noarch/pywin32-on-windows-0.1.0-pyh1179c8e_3.tar.bz2 - sha256: 6502696aaef571913b22a808b15c185bd8ea4aabb952685deb29e6a6765761cb - md5: 2807a0becd1d986fe1ef9b7f8135f215 - depends: - - __unix - - python >=2.7 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 4856 - timestamp: 1646866525560 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py311hda3d55a_1.conda - sha256: b1f6b3a907e36f7af486faf3892f47fab42993c13c934cc19855bbae227f2b18 - md5: e5dd9afed138ff193d4593f1b15a388b - depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - winpty - license: MIT - license_family: MIT - purls: - - pkg:pypi/pywinpty?source=hash-mapping - size: 215911 - timestamp: 1759557817579 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.15-py313h5813708_1.conda - sha256: d34a7cd0a4a7dc79662cb6005e01d630245d9a942e359eb4d94b2fb464ed2552 - md5: 8f01ed27e2baa455e753301218e054fd - depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - winpty - license: MIT - license_family: MIT - purls: - - pkg:pypi/pywinpty?source=hash-mapping - size: 216075 - timestamp: 1759556799508 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda - sha256: c9a6cd2c290d7c3d2b30ea34a0ccda30f770e8ddb2937871f2c404faf60d0050 - md5: a24add9a3bababee946f3bc1c829acfe - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 206190 - timestamp: 1770223702917 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py313h3dea7bd_1.conda - sha256: ef7df29b38ef04ec67a8888a4aa039973eaa377e8c4b59a7be0a1c50cd7e4ac6 - md5: f256753e840c3cd3766488c9437a8f8b - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=compressed-mapping - size: 201616 - timestamp: 1770223543730 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py311hc290fe0_1.conda - sha256: 984e73d7957460689e10533059de8adb38a308853d298900a37acc58edd84cec - md5: e4b908da7cd496b3fa6798c0f60a2a19 - depends: - - __osx >=11.0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 192948 - timestamp: 1770223655988 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py313h65a2061_1.conda - sha256: 950725516f67c9691d81bb8dde8419581c5332c5da3da10c9ba8cbb1698b825d - md5: 5d0c8b92128c93027632ca8f8dc1190f - depends: - - __osx >=11.0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 188763 - timestamp: 1770224094408 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda - sha256: 301c3ba100d25cd5ae37895988ee3ab986210d4d972aa58efed948fbe857773d - md5: a0153c033dc55203e11d1cac8f6a9cf2 - depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 187108 - timestamp: 1770223467913 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py313hd650c13_1.conda - sha256: dfaed50de8ee72a51096163b87631921688851001e38c78a841eba1ae8b35889 - md5: c1bdb8dd255c79fb9c428ad25cc6ee54 - depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 180992 - timestamp: 1770223457761 -- pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - name: pyyaml-env-tag - version: '1.1' - sha256: 17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 + - sciline>=25.11.0 + - scipp>=26.3.1 + - scippneutron>=25.11.1 + - scippnexus>=25.6.0 + - graphviz>=0.20 ; extra == 'test' + - ipywidgets>=8.1 ; extra == 'test' + - matplotlib>=3.10.7 ; extra == 'test' + - numba>=0.63 ; extra == 'test' + - pooch>=1.9.0 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - scipy>=1.14 ; extra == 'test' + - tof>=25.12.0 ; extra == 'test' + - autodoc-pydantic ; extra == 'docs' + - graphviz>=0.20 ; extra == 'docs' + - ipykernel ; extra == 'docs' + - ipython!=8.7.0 ; extra == 'docs' + - ipywidgets>=8.1 ; extra == 'docs' + - myst-parser ; extra == 'docs' + - nbsphinx ; extra == 'docs' + - numba>=0.63 ; extra == 'docs' + - plopp ; extra == 'docs' + - pydata-sphinx-theme>=0.14 ; extra == 'docs' + - sphinx>=7 ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-design ; extra == 'docs' + - tof>=25.12.0 ; extra == 'docs' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: matplotlib + version: 3.10.9 + sha256: 8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f requires_dist: - - pyyaml + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8a/17/a3918541fd0ddefe024a69de6d16aa7b46d36ac19562adaa63c7fa180eff/greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: greenlet + version: 3.5.0 + sha256: 2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + name: refnx + version: 0.1.63 + sha256: 3a12accac6e469fd2c0ef49357301299f6b2e4a9ecdfdfb90b592dad59214eb9 + requires_dist: + - numpy>=2.0 + - scipy + - orsopy + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - traitlets ; extra == 'all' + - matplotlib ; extra == 'all' + - xlrd ; extra == 'all' + - h5py ; extra == 'all' + - jupyter ; extra == 'all' + - tqdm ; extra == 'all' + - pymc ; extra == 'all' + - pytensor ; extra == 'all' + - attrs ; extra == 'all' + - pandas ; extra == 'all' + - pyparsing ; extra == 'all' + - periodictable ; extra == 'all' + - pyqt6 ; extra == 'all' + - qtpy ; extra == 'all' + - corner ; extra == 'all' + - numba ; extra == 'all' + - pytest ; extra == 'test' + - uncertainties ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/8a/a1/8d812e53a5da1687abb10445275d41a8b13adb781bbf7196ddbcf8d88505/lazy_loader-0.5-py3-none-any.whl + name: lazy-loader + version: '0.5' + sha256: ab0ea149e9c554d4ffeeb21105ac60bed7f3b4fd69b1d2360a4add51b170b005 + requires_dist: + - packaging + - pytest>=8.0 ; extra == 'test' + - pytest-cov>=5.0 ; extra == 'test' + - coverage[toml]>=7.2 ; extra == 'test' + - pre-commit==4.3.0 ; extra == 'lint' + - changelist==0.5 ; extra == 'dev' + - spin==0.15 ; extra == 'dev' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda - sha256: 4137226663b353919396f8cf239971cfa54107cd077cf3b65e979ba3e1f8a037 - md5: 759edfe34f07c5c4565b6c5ec0c7fb17 - depends: - - python - - libgcc >=14 - - libstdcxx >=14 - - __glibc >=2.17,<3.0.a0 - - zeromq >=4.3.5,<4.4.0a0 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 383627 - timestamp: 1771716979818 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda - noarch: python - sha256: be66c1f85c3b48137200d62c12d918f4f8ad329423daef04fed292818efd3c28 - md5: 082985717303dab433c976986c674b35 - depends: - - python - - libgcc >=14 - - libstdcxx >=14 - - __glibc >=2.17,<3.0.a0 - - zeromq >=4.3.5,<4.4.0a0 - - _python_abi3_support 1.* - - cpython >=3.12 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 211567 - timestamp: 1771716961404 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py311h745ac33_2.conda - sha256: c5d65e1192241d764a68eb0e95ef3ec4800a7e8584260aa2bdcfad0a2d769609 - md5: 9648524ed194922a084f0c2c2c2ada6a - depends: - - python - - __osx >=11.0 - - python 3.11.* *_cpython - - libcxx >=19 - - zeromq >=4.3.5,<4.4.0a0 - - python_abi 3.11.* *_cp311 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 359869 - timestamp: 1771717160649 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_2.conda - noarch: python - sha256: 2f31f799a46ed75518fae0be75ecc8a1b84360dbfd55096bc2fe8bd9c797e772 - md5: 2f6b79700452ef1e91f45a99ab8ffe5a - depends: - - python - - libcxx >=19 - - __osx >=11.0 - - _python_abi3_support 1.* - - cpython >=3.12 - - zeromq >=4.3.5,<4.4.0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 191641 - timestamp: 1771717073430 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py311hff25285_2.conda - sha256: d37e831618e8df0506d32e16820adab550b74b36d039da753f7543bb967b700d - md5: 0ad824e928af5d6200a97649d810ab2b - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - - zeromq >=4.3.5,<4.3.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 363314 - timestamp: 1771716977369 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py312h343a6d4_2.conda - noarch: python - sha256: d84bcc19a945ca03d1fd794be3e9896ab6afc9f691d58d9c2da514abe584d4df - md5: eb1ec67a70b4d479f7dd76e6c8fe7575 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - zeromq >=4.3.5,<4.3.6.0a0 - - _python_abi3_support 1.* - - cpython >=3.12 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 183235 - timestamp: 1771716967192 -- conda: https://conda.anaconda.org/conda-forge/noarch/questionary-2.1.1-pyhd8ed1ab_0.conda - sha256: 0604c6dff3af5f53e34fceb985395d08287137f220450108a795bcd1959caf14 - md5: 34fa231b5c5927684b03bb296bb94ddc - depends: - - prompt_toolkit >=2.0,<4.0 - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/questionary?source=hash-mapping - size: 31257 - timestamp: 1757356458097 -- pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - name: radon - version: 6.0.1 - sha256: 632cc032364a6f8bb1010a2f6a12d0f14bc7e5ede76585ef29dc0cecf4cd8859 +- pypi: https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl + name: numpy + version: 2.4.4 + sha256: 86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl + name: traittypes + version: 0.2.3 + sha256: 49016082ce740d6556d9bb4672ee2d899cd14f9365f17cbb79d5d96b47096d4e requires_dist: - - mando>=0.6,<0.8 - - colorama==0.4.1 ; python_full_version < '3.5' - - colorama>=0.4.1 ; python_full_version >= '3.5' - - tomli>=2.0.1 ; extra == 'toml' -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 - md5: d7d95fc8287ea7bf33e0e7116d2b95ec - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 345073 - timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 - md5: f8381319127120ce51e081dce4865cf4 - depends: - - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 313930 - timestamp: 1765813902568 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 - md5: 870293df500ca7e18bedefa5838a22ab - depends: - - attrs >=22.2.0 - - python >=3.10 - - rpds-py >=0.7.0 - - typing_extensions >=4.4.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/referencing?source=hash-mapping - size: 51788 - timestamp: 1760379115194 -- pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - name: refl1d - version: 1.0.1 - sha256: 8cc52121790df465e3a659d0fb0298f2501256c6f2d7fca26085927297112eb1 + - traitlets>=4.2.2 + - numpy ; extra == 'test' + - pandas ; extra == 'test' + - xarray ; extra == 'test' + - pytest ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/8e/63/981401c5680c1eb30893f00a19641ac80db5d1e7086c62cb4b13ed813038/lxml-6.1.0-cp313-cp313-win_amd64.whl + name: lxml + version: 6.1.0 + sha256: 4a1503c56e4e2b38dc76f2f2da7bae69670c0f1933e27cfa34b2fa5876410b16 + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + name: uncertainties + version: 3.2.3 + sha256: 313353900d8f88b283c9bad81e7d2b2d3d4bcc330cbace35403faaed7e78890a + requires_dist: + - numpy ; extra == 'arrays' + - pytest ; extra == 'test' + - pytest-codspeed ; extra == 'test' + - pytest-cov ; extra == 'test' + - scipy ; extra == 'test' + - sphinx ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - python-docs-theme ; extra == 'doc' + - uncertainties[arrays,doc,test] ; extra == 'all' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + name: paginate + version: 0.5.7 + sha256: b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 requires_dist: - - bumps==1.0.4 - - matplotlib - - numba - - numpy - - periodictable - - scipy - - orsopy - - ipython ; extra == 'dev' - - matplotlib ; extra == 'dev' - - nbsphinx ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydantic ; extra == 'dev' - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - ruff ; extra == 'dev' - - sphinx<8.2 ; extra == 'dev' - - versioningit ; extra == 'dev' - - wxpython ; extra == 'full' - - ipython ; extra == 'full' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/8a/46/7e2d150dd574039c2f8d09c4e102bb90a6cb6634be4040fc29f212fc42bf/refnx-0.1.63-cp311-abi3-win_amd64.whl + - tox ; extra == 'dev' + - black ; extra == 'lint' +- pypi: https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl + name: plotly + version: 6.7.0 + sha256: ac8aca1c25c663a59b5b9140a549264a5badde2e057d79b8c772ae2920e32ff0 + requires_dist: + - narwhals>=1.15.1 + - packaging + - anywidget ; extra == 'dev' + - build ; extra == 'dev' + - colorcet ; extra == 'dev' + - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev' + - geopandas ; extra == 'dev' + - inflect ; extra == 'dev' + - jupyterlab ; extra == 'dev' + - kaleido>=1.1.0 ; extra == 'dev' + - numpy>=1.22 ; extra == 'dev' + - orjson ; extra == 'dev' + - pandas ; extra == 'dev' + - pdfrw ; extra == 'dev' + - pillow ; extra == 'dev' + - plotly-geo ; extra == 'dev' + - polars[timezone] ; extra == 'dev' + - pyarrow ; extra == 'dev' + - pyshp ; extra == 'dev' + - pytest ; extra == 'dev' + - pytz ; extra == 'dev' + - requests ; extra == 'dev' + - ruff==0.11.12 ; extra == 'dev' + - scikit-image ; extra == 'dev' + - scipy ; extra == 'dev' + - shapely ; extra == 'dev' + - statsmodels ; extra == 'dev' + - vaex ; python_full_version < '3.10' and extra == 'dev' + - xarray ; extra == 'dev' + - build ; extra == 'dev-build' + - jupyterlab ; extra == 'dev-build' + - pytest ; extra == 'dev-build' + - requests ; extra == 'dev-build' + - ruff==0.11.12 ; extra == 'dev-build' + - pytest ; extra == 'dev-core' + - requests ; extra == 'dev-core' + - ruff==0.11.12 ; extra == 'dev-core' + - anywidget ; extra == 'dev-optional' + - build ; extra == 'dev-optional' + - colorcet ; extra == 'dev-optional' + - fiona<=1.9.6 ; python_full_version < '3.9' and extra == 'dev-optional' + - geopandas ; extra == 'dev-optional' + - inflect ; extra == 'dev-optional' + - jupyterlab ; extra == 'dev-optional' + - kaleido>=1.1.0 ; extra == 'dev-optional' + - numpy>=1.22 ; extra == 'dev-optional' + - orjson ; extra == 'dev-optional' + - pandas ; extra == 'dev-optional' + - pdfrw ; extra == 'dev-optional' + - pillow ; extra == 'dev-optional' + - plotly-geo ; extra == 'dev-optional' + - polars[timezone] ; extra == 'dev-optional' + - pyarrow ; extra == 'dev-optional' + - pyshp ; extra == 'dev-optional' + - pytest ; extra == 'dev-optional' + - pytz ; extra == 'dev-optional' + - requests ; extra == 'dev-optional' + - ruff==0.11.12 ; extra == 'dev-optional' + - scikit-image ; extra == 'dev-optional' + - scipy ; extra == 'dev-optional' + - shapely ; extra == 'dev-optional' + - statsmodels ; extra == 'dev-optional' + - vaex ; python_full_version < '3.10' and extra == 'dev-optional' + - xarray ; extra == 'dev-optional' + - numpy>=1.22 ; extra == 'express' + - kaleido>=1.1.0 ; extra == 'kaleido' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl name: refnx version: 0.1.63 - sha256: 3a12accac6e469fd2c0ef49357301299f6b2e4a9ecdfdfb90b592dad59214eb9 + sha256: 9bc88eba956e97892805d2fb18a7268780f943c5d74feb5d1c58f5ae90699fa2 requires_dist: - numpy>=2.0 - scipy @@ -11370,1062 +11439,1200 @@ packages: - pytest ; extra == 'test' - uncertainties ; extra == 'test' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/90/df/cbd75ba033d712a7bbe8efff2a764c15a3904003f78ed3c19f259c91a4a4/refnx-0.1.63-cp311-abi3-macosx_11_0_arm64.whl - name: refnx - version: 0.1.63 - sha256: 9bc88eba956e97892805d2fb18a7268780f943c5d74feb5d1c58f5ae90699fa2 +- pypi: https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl + name: graphviz + version: '0.21' + sha256: 54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42 + requires_dist: + - build ; extra == 'dev' + - wheel ; extra == 'dev' + - twine ; extra == 'dev' + - flake8 ; extra == 'dev' + - flake8-pyproject ; extra == 'dev' + - pep8-naming ; extra == 'dev' + - tox>=3 ; extra == 'dev' + - pytest>=7,<8.1 ; extra == 'test' + - pytest-mock>=3 ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - sphinx>=5,<7 ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinx-rtd-theme>=0.2.5 ; extra == 'docs' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl + name: typeguard + version: 4.5.1 + sha256: 44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 + requires_dist: + - importlib-metadata>=3.6 ; python_full_version < '3.10' + - typing-extensions>=4.14.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: coverage + version: 7.13.5 + sha256: ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/93/6e/bd7fbfacca077bc6f34f1a1109800a2c41ab50f4704d3a0507ba41009915/freetype_py-2.5.1-py3-none-win_amd64.whl + name: freetype-py + version: 2.5.1 + sha256: 0b7f8e0342779f65ca13ef8bc103938366fecade23e6bb37cb671c2b8ad7f124 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl + name: xhtml2pdf + version: 0.2.17 + sha256: 61a7ecac829fed518f7dbcb916e9d56bea6e521e02e54644b3d0ca33f0658315 + requires_dist: + - arabic-reshaper>=3.0.0 + - html5lib>=1.1 + - pillow>=8.1.1 + - pyhanko>=0.12.1 + - pyhanko-certvalidator>=0.19.5 + - pypdf>=3.1.0 + - python-bidi>=0.5.0 + - reportlab>=4.0.4,<5 + - svglib>=1.2.1 + - reportlab[pycairo]>=4.0.4,<5 ; extra == 'pycairo' + - reportlab[renderpm]>=4.0.4,<5 ; extra == 'renderpm' + - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'test' + - tox ; extra == 'test' + - coverage>=5.3 ; extra == 'test' + - sphinx>=6 ; extra == 'docs' + - sphinx-rtd-theme>=0.5.0 ; extra == 'docs' + - sphinx-reredirects>=0.1.3 ; extra == 'docs' + - build ; extra == 'release' + - twine ; extra == 'release' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + name: radon + version: 6.0.1 + sha256: 632cc032364a6f8bb1010a2f6a12d0f14bc7e5ede76585ef29dc0cecf4cd8859 + requires_dist: + - mando>=0.6,<0.8 + - colorama==0.4.1 ; python_full_version < '3.5' + - colorama>=0.4.1 ; python_full_version >= '3.5' + - tomli>=2.0.1 ; extra == 'toml' +- pypi: https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl + name: identify + version: 2.6.19 + sha256: 20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a + requires_dist: + - ukkonen ; extra == 'license' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/95/95/685e5a31f6c4cc24826d3a0df9e6a4bcf13d00f90d0c1f1060f13f5c16f8/python_bidi-0.6.9-cp313-cp313-macosx_11_0_arm64.whl + name: python-bidi + version: 0.6.9 + sha256: c3e4445f0fd1e2c16d3efdb28622a38f57ab4b971eb47803a334be477cee173e + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/96/5d/0c59079aa7ef34980a5925a06a90ad2b7c94e486c194b3527d557cabb042/cryspy-0.11.0-py3-none-any.whl + name: cryspy + version: 0.11.0 + sha256: 0b650655a0fbdc3cfcb28826c2ab9fbc5f491e32e1ea9a47d9b75976cd43f26f requires_dist: - - numpy>=2.0 + - numpy - scipy - - orsopy - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - traitlets ; extra == 'all' - - matplotlib ; extra == 'all' - - xlrd ; extra == 'all' - - h5py ; extra == 'all' - - jupyter ; extra == 'all' - - tqdm ; extra == 'all' - - pymc ; extra == 'all' - - pytensor ; extra == 'all' - - attrs ; extra == 'all' - - pandas ; extra == 'all' - - pyparsing ; extra == 'all' - - periodictable ; extra == 'all' - - pyqt6 ; extra == 'all' - - qtpy ; extra == 'all' - - corner ; extra == 'all' - - numba ; extra == 'all' - - pytest ; extra == 'test' - - uncertainties ; extra == 'test' + - pycifstar + - matplotlib +- pypi: https://files.pythonhosted.org/packages/96/b3/650500c2eab4534d98e9166f4298e0f3c69c742afdf24e6eabccd1f16ad8/numba-0.65.1-cp311-cp311-macosx_12_0_arm64.whl + name: numba + version: 0.65.1 + sha256: 7020d74b19cdb8cff16506542fdd510756e28c5e7f3bd0b7f574f0f42272fcd9 + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + name: contourpy + version: 1.3.3 + sha256: d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: refnx - version: 0.1.63 - sha256: 4f397b0d6e18ac1bb793372ec92c9f4a122383387a706dea456df5a2c90dff5e +- pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl + name: contourpy + version: 1.3.3 + sha256: 3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 requires_dist: - - numpy>=2.0 - - scipy - - orsopy - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - traitlets ; extra == 'all' - - matplotlib ; extra == 'all' - - xlrd ; extra == 'all' - - h5py ; extra == 'all' - - jupyter ; extra == 'all' - - tqdm ; extra == 'all' - - pymc ; extra == 'all' - - pytensor ; extra == 'all' - - attrs ; extra == 'all' - - pandas ; extra == 'all' - - pyparsing ; extra == 'all' - - periodictable ; extra == 'all' - - pyqt6 ; extra == 'all' - - qtpy ; extra == 'all' - - corner ; extra == 'all' - - numba ; extra == 'all' - - pytest ; extra == 'test' - - uncertainties ; extra == 'test' + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/1c/13/bc43591a54dd38ac5c19e7e849f0311d879737a0d07e032e5be79849a5fb/reportlab-4.5.0-py3-none-any.whl - name: reportlab - version: 4.5.0 - sha256: b8cc8996947d84e805368b47b2376070966f091d029351a0d8a1f238984c2c7f +- pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + name: asteval + version: 1.0.8 + sha256: 6c64385c6ff859a474953c124987c7ee8354d781c76509b2c598741c4d1d28e9 requires_dist: - - pillow>=9.0.0 - - charset-normalizer - - rl-accel>=0.9.0,<1.1 ; extra == 'accel' - - rl-renderpm>=4.0.3,<4.1 ; extra == 'renderpm' - - rlpycairo>=0.2.0,<1 ; extra == 'pycairo' - - freetype-py>=2.3.0,<2.4 ; extra == 'pycairo' - - rlbidi ; extra == 'bidi' - - uharfbuzz ; extra == 'shaping' - requires_python: '>=3.9,<4' -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda - sha256: 7f2c24dd3bd3c104a1d2c9a10ead5ed6758b0976b74f972cfe9c19884ccc4241 - md5: 9659f587a8ceacc21864260acd02fc67 - depends: - - python >=3.10 - - certifi >=2023.5.7 - - charset-normalizer >=2,<4 - - idna >=2.5,<4 - - urllib3 >=1.26,<3 - - python - constrains: - - chardet >=3.0.2,<8 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/requests?source=compressed-mapping - size: 63728 - timestamp: 1777030058920 -- conda: https://conda.anaconda.org/conda-forge/noarch/returns-0.27.0-pyhc364b38_0.conda - sha256: 3b45efeae771f1a20307b36ecdb3a8911a89c05382836b50c62b0a99d8d3dfd8 - md5: da94ff04d97ec5efc42cbe5da3c43a84 - depends: - - python >=3.11 - - typing_extensions >=4.0,<5.0 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/returns?source=hash-mapping - size: 100559 - timestamp: 1776176903101 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda - sha256: 2e4372f600490a6e0b3bac60717278448e323cab1c0fecd5f43f7c56535a99c5 - md5: 36de09a8d3e5d5e6f4ee63af49e59706 - depends: - - python >=3.9 - - six - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3339-validator?source=hash-mapping - size: 10209 - timestamp: 1733600040800 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 - md5: 912a71cc01012ee38e6b90ddd561e36f - depends: - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3986-validator?source=hash-mapping - size: 7818 - timestamp: 1598024297745 -- conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - sha256: 70001ac24ee62058557783d9c5a7bbcfd97bd4911ef5440e3f7a576f9e43bc92 - md5: 7234f99325263a5af6d4cd195035e8f2 - depends: - - python >=3.9 - - lark >=1.2.2 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/rfc3987-syntax?source=hash-mapping - size: 22913 - timestamp: 1752876729969 -- pypi: https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl - name: rich - version: 15.0.0 - sha256: 33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb + - build ; extra == 'dev' + - twine ; extra == 'dev' + - sphinx ; extra == 'doc' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - coverage ; extra == 'test' + - asteval[dev,doc,test] ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + name: bidict + version: 0.23.1 + sha256: 5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl + name: tabulate + version: 0.10.0 + sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 + requires_dist: + - wcwidth ; extra == 'widechars' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: yarl + version: 1.23.0 + sha256: 99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.5 + sha256: a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl + name: pytest-cov + version: 7.1.0 + sha256: a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 requires_dist: - - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' - - markdown-it-py>=2.2.0 - - pygments>=2.13.0,<3.0.0 - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/6a/00/d26b61e82163a59334e9f2ae31ba95ac01922da3792f090e11762d4422e8/rlpycairo-0.4.0-py3-none-any.whl - name: rlpycairo - version: 0.4.0 - sha256: 3ce83825d5761c03bc3571c7db12a336ad51417e63189e3512d11b8922576aa9 + - coverage[toml]>=7.10.6 + - pluggy>=1.2 + - pytest>=7 + - process-tests ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - virtualenv ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + name: autopep8 + version: 2.3.2 + sha256: ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128 requires_dist: - - pycairo>=1.20.0 - - freetype-py>=2.3 + - pycodestyle>=2.12.0 + - tomli ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + name: networkx + version: 3.6.1 + sha256: d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 + requires_dist: + - asv ; extra == 'benchmarking' + - virtualenv ; extra == 'benchmarking' + - numpy>=1.25 ; extra == 'default' + - scipy>=1.11.2 ; extra == 'default' + - matplotlib>=3.8 ; extra == 'default' + - pandas>=2.0 ; extra == 'default' + - pre-commit>=4.1 ; extra == 'developer' + - mypy>=1.15 ; extra == 'developer' + - sphinx>=8.0 ; extra == 'doc' + - pydata-sphinx-theme>=0.16 ; extra == 'doc' + - sphinx-gallery>=0.18 ; extra == 'doc' + - numpydoc>=1.8.0 ; extra == 'doc' + - pillow>=10 ; extra == 'doc' + - texext>=0.6.7 ; extra == 'doc' + - myst-nb>=1.1 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - osmnx>=2.0.0 ; extra == 'example' + - momepy>=0.7.2 ; extra == 'example' + - contextily>=1.6 ; extra == 'example' + - seaborn>=0.13 ; extra == 'example' + - cairocffi>=1.7 ; extra == 'example' + - igraph>=0.11 ; extra == 'example' + - scikit-learn>=1.5 ; extra == 'example' + - iplotx>=0.9.0 ; extra == 'example' + - lxml>=4.6 ; extra == 'extra' + - pygraphviz>=1.14 ; extra == 'extra' + - pydot>=3.0.1 ; extra == 'extra' + - sympy>=1.10 ; extra == 'extra' + - build>=0.10 ; extra == 'release' + - twine>=4.0 ; extra == 'release' + - wheel>=0.40 ; extra == 'release' + - changelist==0.5 ; extra == 'release' + - pytest>=7.2 ; extra == 'test' + - pytest-cov>=4.0 ; extra == 'test' + - pytest-xdist>=3.0 ; extra == 'test' + - pytest-mpl ; extra == 'test-extras' + - pytest-randomly ; extra == 'test-extras' + requires_python: '>=3.11,!=3.14.1' +- pypi: https://files.pythonhosted.org/packages/9f/9b/50835e8fd86073fa7aa921df61b4cebc1f0ff400e4338541675cb72b5507/pycifrw-5.0.1-cp313-cp313-win_amd64.whl + name: pycifrw + version: 5.0.1 + sha256: 8632df76b99932408ab432e09b30aa9a6c390df884a5f34f1e1f76201e625156 + requires_dist: + - prettytable + - ply + - numpy +- pypi: https://files.pythonhosted.org/packages/a0/22/b8d873f6466b20aa563fc9b33acd48dec89a07803ddaa2f1c8ca1cd33126/numba-0.65.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: numba + version: 0.65.1 + sha256: c09f49117ef255e1f1c6dad0c7a1ed39868243862a73be5706793241a3755f1b + requires_dist: + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + name: gitdb + version: 4.0.12 + sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + requires_dist: + - smmap>=3.0.1,<6 requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda - sha256: bf5e6197fb08b8c6e421ca0126e966b7c3ae62b84d7b98523356b4fd5ae6f8ae - md5: 3893f7b40738f9fe87510cb4468cdda5 - depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.11.* *_cp311 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 383153 - timestamp: 1764543197251 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py313h843e2db_0.conda - sha256: 076d26e51c62c8ecfca6eb19e3c1febdd7632df1990a7aa53da5df5e54482b1c - md5: 779e3307a0299518713765b83a36f4b1 - depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.13.* *_cp313 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 383230 - timestamp: 1764543223529 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py311h71babbd_0.conda - sha256: 15873755f078583cea046f7ca7fc0d5348d1f29a16a30b73bdb53dd62f2ba379 - md5: 4408829b022e8e0d19365c0c00be00c4 - depends: - - python - - python 3.11.* *_cpython - - __osx >=11.0 - - python_abi 3.11.* *_cp311 - constrains: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 357600 - timestamp: 1764543142990 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py313h2c089d5_0.conda - sha256: db63344f91e8bfe77703c6764aa9eeafb44d165e286053214722814eabda0264 - md5: 190c2d0d4e98ec97df48cdb74caf44d8 - depends: - - python - - __osx >=11.0 - - python 3.13.* *_cp313 - - python_abi 3.13.* *_cp313 - constrains: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 358961 - timestamp: 1764543165314 -- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py311hf51aa87_0.conda - sha256: 6edeab1412def450e72f0e96a5d8bb31a2a0b4e56624699c916d3bafd4d9b475 - md5: 43ab63451a9df29f2c499da524665de9 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.11.* *_cp311 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 241288 - timestamp: 1764543026991 -- conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.30.0-py313hfbe8231_0.conda - sha256: 27bd383787c0df7a0a926b11014fd692d60d557398dcf1d50c55aa2378507114 - md5: 58ae648b12cfa6df3923b5fd219931cb - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.13.* *_cp313 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 243419 - timestamp: 1764543047271 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.12-h994f30f_0.conda - noarch: python - sha256: 98c771464ed93a2733bae460c39cfa9640feb20972d2e651b44e85db296942eb - md5: 3c8f229055ad244fa3a97c6c45b77099 - depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 9266480 - timestamp: 1778119386343 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.12-hbd3f8a3_0.conda - noarch: python - sha256: 91992a557456cbe9980e8ffb0f0d1200f65f741adeefc7ecf568d1935690a7bc - md5: 7151a0851207b88c0031f388a7825e9b - depends: - - python - - __osx >=11.0 - constrains: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 8485007 - timestamp: 1778119519471 -- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.15.12-hd7ccaa8_0.conda - noarch: python - sha256: 9b47c39449fd0102315bb62bd632707a754d32cf6c6f08d2a9c74b0a476f2282 - md5: 2db0d3419f3e6fc05516da561f81cda5 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 9719930 - timestamp: 1778119435755 -- pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl - name: sciline - version: 25.11.1 - sha256: 13c378287b8157e819b9b67d7e973c65bc6bdc545a3602d18204c365b0c336f9 +- pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl + name: sympy + version: 1.14.0 + sha256: e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5 + requires_dist: + - mpmath>=1.1.0,<1.4 + - pytest>=7.1.0 ; extra == 'dev' + - hypothesis>=6.70.0 ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a2/50/59227d06bdc96e23322713c381af4e77420949d8cd8a042c79e0043096cc/llvmlite-0.47.0-cp311-cp311-win_amd64.whl + name: llvmlite + version: 0.47.0 + sha256: c37d6eb7aaabfa83ab9c2ff5b5cdb95a5e6830403937b2c588b7490724e05327 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl + name: ply + version: '3.11' + sha256: 096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce +- pypi: https://files.pythonhosted.org/packages/a3/8c/db8e79c4c744ebae1dcf25f7dbcc5d7df912cdbcdf7221e761479e8bd04b/gemmi-0.7.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: gemmi + version: 0.7.5 + sha256: 750b4d9751aaf1460ac4f0f45308ddced25f47bcf7a30355eb3b1f779f03952a + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl + name: varname + version: 1.0.0 + sha256: 1125bfe981c3bbbe56988f5cb85fdcd7cad923b153283c2d464aea8b4c833d51 requires_dist: - - cyclebane>=24.6.0 - - pytest ; extra == 'test' - - pytest-randomly>=3 ; extra == 'test' - - dask ; extra == 'test' - - graphviz ; extra == 'test' - - jsonschema ; extra == 'test' - - numpy ; extra == 'test' - - pandas ; extra == 'test' - - pydantic ; extra == 'test' - - rich ; extra == 'test' - - rich ; extra == 'progress' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/2e/75/5604f4d17ab607510d4702f156329194d8edfff7e29644ca9200b085e9a2/scipp-26.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: scipp - version: 26.3.1 - sha256: 993706e7c31f0317be2db5f528f9142ba67b2e52d7af174fcad195f702e1d6c7 + - executing>=2.1 + - typing-extensions>=4.13 ; python_full_version < '3.10' + - asttokens==3.* ; extra == 'all' + - pure-eval==0.* ; extra == 'all' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + name: verspec + version: 0.1.0 + sha256: 741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 requires_dist: - - numpy>=2 + - coverage ; extra == 'test' + - flake8>=3.7 ; extra == 'test' + - mypy ; extra == 'test' + - pretend ; extra == 'test' - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/37/fd/22621d3ee9e3ee87ef4c89b63bba55b265ab85039b3c1ba88ed2380a24c1/scipp-26.3.1-cp313-cp313-win_amd64.whl - name: scipp - version: 26.3.1 - sha256: 03c6dbf8936a2ed62587c5abe8ab5266a5098834a0709321ce799bd1328eb3e6 +- pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + name: wsproto + version: 1.3.2 + sha256: 61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584 requires_dist: - - numpy>=2 - - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/60/54/5011adb56853caabfd90686c2e543d1e3c76a8ef2755809b7e12e3f3583b/scipp-26.3.1-cp311-cp311-macosx_14_0_arm64.whl - name: scipp - version: 26.3.1 - sha256: 67d275fc83b062053df9aa7ce3af4d2205109c2bc3ab22467bcd73ceb0a83df2 + - h11>=0.16.0,<1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl + name: kiwisolver + version: 1.5.0 + sha256: dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + name: mkdocs-markdownextradata-plugin + version: 0.2.6 + sha256: 34dd40870781784c75809596b2d8d879da783815b075336d541de1f150c94242 requires_dist: - - numpy>=2 - - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/79/fe/b14d806894cf05178f1e77d0d619f071db50cf698bc654c54f9241223bcf/scipp-26.3.1-cp313-cp313-macosx_14_0_arm64.whl - name: scipp - version: 26.3.1 - sha256: 8dfe8adedb5cba05acaaea15e3b6fe1820ac2f497e87c1e581ba4be9d82c53bb + - mkdocs + - pyyaml + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl + name: markdown-it-py + version: 4.1.0 + sha256: d4939a62a2dd0cd9cb80a191a711ba1d39bac8ed5ef9e9966895b0171c01c46d + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a8/b1/3338e121cbd4c8a126b8ccb1061170c2ce51a53f678c502793ea49c6fd6d/chardet-7.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.4.3 + sha256: bfc134b70c846c21ead8e43ada3ae1a805fff732f6922f8abcf2ff27b8f6493d + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + name: python-engineio + version: 4.13.1 + sha256: f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399 + requires_dist: + - simple-websocket>=0.10.0 + - requests>=2.21.0 ; extra == 'client' + - websocket-client>=0.54.0 ; extra == 'client' + - aiohttp>=3.11 ; extra == 'asyncio-client' + - tox ; extra == 'dev' + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + name: execnet + version: 2.1.2 + sha256: 67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec + requires_dist: + - hatch ; extra == 'testing' + - pre-commit ; extra == 'testing' + - pytest ; extra == 'testing' + - tox ; extra == 'testing' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + name: jupyterlab-widgets + version: 3.0.16 + sha256: 45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: coverage + version: 7.13.5 + sha256: 78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ac/a6/1ca2d290381911c17975ba00353671217bb9ed6c56f395871b274435b020/python_bidi-0.6.9-cp311-cp311-win_amd64.whl + name: python-bidi + version: 0.6.9 + sha256: be28092eef062fad59e7e0402bf2c1db797ccadedd866a53bbd7ddb97e42cac1 + requires_dist: + - nox ; extra == 'dev' + - pytest ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl + name: click + version: 8.3.3 + sha256: a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 + requires_dist: + - colorama ; sys_platform == 'win32' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + name: yarl + version: 1.23.0 + sha256: 7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl + name: sqlalchemy + version: 2.0.49 + sha256: df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/af/46/661159ad844034ba8b3f4e0516215c41e4ee17db4213d13a82227670764f/sciline-25.11.1-py3-none-any.whl + name: sciline + version: 25.11.1 + sha256: 13c378287b8157e819b9b67d7e973c65bc6bdc545a3602d18204c365b0c336f9 requires_dist: - - numpy>=2 + - cyclebane>=24.6.0 - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' + - pytest-randomly>=3 ; extra == 'test' + - dask ; extra == 'test' + - graphviz ; extra == 'test' + - jsonschema ; extra == 'test' + - numpy ; extra == 'test' + - pandas ; extra == 'test' + - pydantic ; extra == 'test' + - rich ; extra == 'test' + - rich ; extra == 'progress' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: scipp - version: 26.3.1 - sha256: ab5859a24b3150b588dd2c67e68b0c7f07c9444eae501f3b6326d6b4a34cbf10 +- pypi: https://files.pythonhosted.org/packages/af/78/bc3850efda66712370ebb2a52130111b5cbbdee7a5b9d1672aadfc73234f/orsopy-1.2.3-py2.py3-none-any.whl + name: orsopy + version: 1.2.3 + sha256: 11d3ee9a1185467ba4363b24d6b98b268956ee0fb528aeff7ff106b49f363180 requires_dist: - - numpy>=2 - - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl - name: scipp - version: 26.3.1 - sha256: 37877cf07b4f54f224d5465c265d6a1e591d605d0c23dd350a4b48d95c26ab7b + - pyyaml>=5.4.1 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl + name: coverage + version: 7.13.5 + sha256: 258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9 requires_dist: - - numpy>=2 + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b0/65/5e088a45d0f43cd814bc5bec521c051d42005a472e804b1a36c48dada09b/h5py-3.16.0-cp313-cp313-macosx_11_0_arm64.whl + name: h5py + version: 3.16.0 + sha256: 42108e93326c50c2810025aade9eac9d6827524cdccc7d4b75a546e5ab308edb + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b1/10/31932775c94a86814f76b41c4a772b52abfb0e6125324f32c6da1196c297/chardet-7.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.4.3 + sha256: 4c3da294de1a681097848ab58bd3f2771a674f8039d2d87a5538b28856b815e9 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl + name: virtualenv + version: 21.3.1 + sha256: d1a71cf58f2f9228fff23a1f6ec15d39785c6b32e03658d104974247145edd35 + requires_dist: + - distlib>=0.3.7,<1 + - filelock>=3.24.2,<4 ; python_full_version >= '3.10' + - filelock>=3.16.1,<=3.19.1 ; python_full_version < '3.10' + - importlib-metadata>=6.6 ; python_full_version < '3.8' + - platformdirs>=3.9.1,<5 + - python-discovery>=1.2.2 + - typing-extensions>=4.13.2 ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/b1/8b/88f16936a8e8070a83d36239555227ecd91728f9ef222c5382cda07e0fd6/h5netcdf-1.8.1-py3-none-any.whl + name: h5netcdf + version: 1.8.1 + sha256: a76ed7cfc9b8a8908ea7057c4e57e27307acff1049b7f5ed52db6c2247636879 + requires_dist: + - packaging + - numpy + - h5py ; extra == 'h5py' + - pyfive>=1.0.0 ; extra == 'pyfive' + - h5pyd ; extra == 'h5pyd' + - h5py ; extra == 'test' + - netcdf4 ; extra == 'test' + - pyfive>=1.0.0 ; extra == 'test' - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/82/9b/cf7e6f157c53d2c8bc0165580350c53939aea3b2a8390ec8e07f0adb82de/scippneutron-26.4.1-py3-none-any.whl - name: scippneutron - version: 26.4.1 - sha256: 3b9865ebdb7923eb25739b7cda624555d45275341000f099c1dcf371b1dd7e35 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl + name: yarl + version: 1.23.0 + sha256: dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 requires_dist: - - python-dateutil>=2.8 - - email-validator>=2 - - h5py>=3.12 - - lazy-loader>=0.4 - - mpltoolbox>=24.6.0 - - numpy>=1.20 - - plopp>=26.4.1 - - pydantic>=2 - - scipp>=24.7.0 - - scippnexus>=23.11.0 - - scipy>=1.7.0 - - scipp[all]>=23.7.0 ; extra == 'all' - - pooch>=1.5 ; extra == 'all' - - hypothesis>=6.100 ; extra == 'test' - - ipympl>0.9.0 ; extra == 'test' - - ipykernel>6.30 ; extra == 'test' - - pace-neutrons>=0.3 ; extra == 'test' - - pooch>=1.5 ; extra == 'test' - - psutil>=5.0 ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - pytest-xdist>=3.0 ; extra == 'test' - - pythreejs>=2.4.1 ; extra == 'test' - - sciline>=25.1.0 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/5c/01/6cb4d63c6b6933be4b7945b2f64638336420f04ea71ca5b9a7539c008bc5/scippnexus-26.1.1-py3-none-any.whl - name: scippnexus - version: 26.1.1 - sha256: 899a0a5e71291b7809d902c17b6c74addf5a805397eabcec557491ff74eead12 + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + name: multidict + version: 6.7.1 + sha256: 960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5 requires_dist: - - scipp>=24.2.0 - - scipy>=1.10.0 - - h5py>=3.12 - - pytest>=7.0 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: scipy - version: 1.17.1 - sha256: 43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4 + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/8f/22bf9df92bbff0eb07842b60f7e63bf7675a9742df628437a9f02d09137f/greenlet-3.5.0-cp313-cp313-win_amd64.whl + name: greenlet + version: 3.5.0 + sha256: 728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl - name: scipy - version: 1.17.1 - sha256: 37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448 + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + name: mdurl + version: 0.1.2 + sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/b3/52/bc858b1665d0dec3a2511f4e6f5c18ea85c0977563d624d597c95d6d0fd7/jupyterquiz-2.9.6.4-py2.py3-none-any.whl + name: jupyterquiz + version: 2.9.6.4 + sha256: f8c4418f6c827454523fc882a30d744b585cb58ac1ae277769c3059d04fc272b +- pypi: https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl + name: markdown-it-py + version: 4.2.0 + sha256: 9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl - name: scipy - version: 1.17.1 - sha256: 7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - pytest-timeout ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b4/5e/bf11645aebb9af7d8d35927c40d3855816a0855c799e8156eeca8d632c90/diffpy_structure-3.4.0-py3-none-any.whl + name: diffpy-structure + version: 3.4.0 + sha256: bd0f06a96635d80316f51ebc0a08003bdeb2cb48c9bb18cbed1455ac60645e48 requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl - name: scipy - version: 1.17.1 - sha256: a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee + - numpy + - pycifrw + - diffpy-utils + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + name: watchdog + version: 6.0.0 + sha256: 20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2 requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl - name: scipy - version: 1.17.1 - sha256: d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + name: validate-pyproject + version: '0.25' + sha256: f9d05e2686beff82f9ea954f582306b036ced3d3feb258c1110f2c2a495b1981 requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' + - fastjsonschema>=2.16.2,<=3 + - packaging>=24.2 ; extra == 'all' + - trove-classifiers>=2021.10.20 ; extra == 'all' + - tomli>=1.2.1 ; python_full_version < '3.11' and extra == 'all' + - validate-pyproject-schema-store ; extra == 'store' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + name: dnspython + version: 2.8.0 + sha256: 01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af + requires_dist: + - black>=25.1.0 ; extra == 'dev' + - coverage>=7.0 ; extra == 'dev' + - flake8>=7 ; extra == 'dev' + - hypercorn>=0.17.0 ; extra == 'dev' + - mypy>=1.17 ; extra == 'dev' + - pylint>=3 ; extra == 'dev' + - pytest-cov>=6.2.0 ; extra == 'dev' + - pytest>=8.4 ; extra == 'dev' + - quart-trio>=0.12.0 ; extra == 'dev' + - sphinx-rtd-theme>=3.0.0 ; extra == 'dev' + - sphinx>=8.2.0 ; extra == 'dev' + - twine>=6.1.0 ; extra == 'dev' + - wheel>=0.45.0 ; extra == 'dev' + - cryptography>=45 ; extra == 'dnssec' + - h2>=4.2.0 ; extra == 'doh' + - httpcore>=1.0.0 ; extra == 'doh' + - httpx>=0.28.0 ; extra == 'doh' + - aioquic>=1.2.0 ; extra == 'doq' + - idna>=3.10 ; extra == 'idna' + - trio>=0.30 ; extra == 'trio' + - wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + name: pyproject-hooks + version: 1.2.0 + sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl + name: numpy + version: 2.4.4 + sha256: 6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: scipy - version: 1.17.1 - sha256: 581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 +- pypi: https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl + name: h5py + version: 3.16.0 + sha256: 9300ad32dea9dfc5171f94d5f6948e159ed93e4701280b0f508773b3f582f402 requires_dist: - - numpy>=1.26.4,<2.7 - - pytest>=8.0.0 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest-xdist ; extra == 'test' - - asv ; extra == 'test' - - mpmath ; extra == 'test' - - gmpy2 ; extra == 'test' - - threadpoolctl ; extra == 'test' - - scikit-umfpack ; extra == 'test' - - pooch ; extra == 'test' - - hypothesis>=6.30 ; extra == 'test' - - array-api-strict>=2.3.1 ; extra == 'test' - - cython ; extra == 'test' - - meson ; extra == 'test' - - ninja ; sys_platform != 'emscripten' and extra == 'test' - - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design>=0.4.0 ; extra == 'doc' - - matplotlib>=3.5 ; extra == 'doc' - - numpydoc ; extra == 'doc' - - jupytext ; extra == 'doc' - - myst-nb>=1.2.0 ; extra == 'doc' - - pooch ; extra == 'doc' - - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - - jupyterlite-pyodide-kernel ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - tabulate ; extra == 'doc' - - click<8.3.0 ; extra == 'dev' - - spin ; extra == 'dev' - - mypy==1.10.0 ; extra == 'dev' - - typing-extensions ; extra == 'dev' - - types-psutil ; extra == 'dev' - - pycodestyle ; extra == 'dev' - - ruff>=0.12.0 ; extra == 'dev' - - cython-lint>=0.12.2 ; extra == 'dev' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh5552912_1.conda - sha256: 8fc024bf1a7b99fc833b131ceef4bef8c235ad61ecb95a71a6108be2ccda63e8 - md5: b70e2d44e6aa2beb69ba64206a16e4c6 - depends: - - __osx - - pyobjc-framework-cocoa - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/send2trash?source=hash-mapping - size: 22519 - timestamp: 1770937603551 -- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyh6dadd2b_1.conda - sha256: 305446a0b018f285351300463653d3d3457687270e20eda37417b12ee386ef76 - md5: 6ac53f3fff2c416d63511843a04646fa - depends: - - __win - - pywin32 - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/send2trash?source=hash-mapping - size: 22864 - timestamp: 1770937641143 -- conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - sha256: 59656f6b2db07229351dfb3a859c35e57cc8e8bcbc86d4e501bff881a6f771f1 - md5: 28eb91468df04f655a57bcfbb35fc5c5 - depends: - - __linux - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/send2trash?source=hash-mapping - size: 24108 - timestamp: 1770937597662 -- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - sha256: 82088a6e4daa33329a30bc26dc19a98c7c1d3f05c0f73ce9845d4eab4924e9e1 - md5: 8e194e7b992f99a5015edbd4ebd38efd - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/setuptools?source=hash-mapping - size: 639697 - timestamp: 1773074868565 -- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - name: shellingham - version: 1.5.4 - sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - name: simple-websocket - version: 1.1.0 - sha256: 4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bd/9a/af61ec03b3116c161fd7a06b9e8a265729a8718458333e8ffbb06d9a3978/numba-0.65.1-cp311-cp311-win_amd64.whl + name: numba + version: 0.65.1 + sha256: df40a5028a975b9ea66f6a2a3f7abbdbd541a863070e34ed367aff21141248e4 requires_dist: - - wsproto - - tox ; extra == 'dev' - - flake8 ; extra == 'dev' + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl + name: kiwisolver + version: 1.5.0 + sha256: beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl + name: kiwisolver + version: 1.5.0 + sha256: 0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/3b/38ff88b347c3e346cda1d3fc1b65a7aa75d40632228d8b8a5d7b58508c24/h5py-3.16.0-cp311-cp311-macosx_11_0_arm64.whl + name: h5py + version: 3.16.0 + sha256: c3f0a0e136f2e95dd0b67146abb6668af4f1a69c81ef8651a2d316e8e01de447 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bf/50/98b146aea0f1cd7531d25f12bea69fa9ce8d1662124f93fb30dc4511b65e/docstring_parser_fork-0.0.14-py3-none-any.whl + name: docstring-parser-fork + version: 0.0.14 + sha256: 4c544f234ef2cc2749a3df32b70c437d77888b1099143a1ad5454452c574b9af + requires_dist: + - docstring-parser[docs] ; extra == 'dev' + - docstring-parser[test] ; extra == 'dev' + - pre-commit>=2.16.0 ; python_full_version >= '3.9' and extra == 'dev' + - pydoctor>=25.4.0 ; extra == 'docs' + - pytest ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/bf/e1/9e8e09ab8fc5c77f228e3271188dc4f569d12692548c42bff81b1fbba5e1/easydiffraction-0.16.0-py3-none-any.whl + name: easydiffraction + version: 0.16.0 + sha256: 2691a1e175974ca79e0ec3c219d92b77f277c38fb3b0b8d25f6f7e99696bf70f + requires_dist: + - asciichartpy + - asteval + - bumps + - colorama + - crysfml + - cryspy + - darkdetect + - dfo-ls + - diffpy-pdffit2 + - diffpy-utils + - essdiffraction + - gemmi + - lmfit + - numpy + - pandas + - plotly + - pooch + - py3dmol + - rich + - scipy + - sympy + - tabulate + - typeguard + - typer + - uncertainties + - varname + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' - pytest ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' - pytest-cov ; extra == 'dev' - - sphinx ; extra == 'docs' - requires_python: '>=3.6' -- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d - md5: 3339e3b65d58accf4ca4fb8748ab16b3 - depends: - - python >=3.9 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/six?source=hash-mapping - size: 18455 - timestamp: 1753199211006 + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.12' +- pypi: https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl + name: aiohttp + version: 3.13.5 + sha256: 69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl + name: aiohttp + version: 3.13.5 + sha256: d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c1/9c/1236dd7d22ed48527286b613c84e3376ea731b65e6734b6e6a0b4d03744c/gemmi-0.7.5-cp313-cp313-macosx_11_0_arm64.whl + name: gemmi + version: 0.7.5 + sha256: c7d8b08c33fe6ba375223306149092440c69cbfbd55c3d3e3436e5fb315a225d + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl name: smmap version: 5.0.3 sha256: c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda - sha256: dce518f45e24cd03f401cb0616917773159a210c19d601c5f2d4e0e5879d30ad - md5: 03fe290994c5e4ec17293cfb6bdce520 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/sniffio?source=hash-mapping - size: 15698 - timestamp: 1762941572482 -- conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda - sha256: 23b71ecf089967d2900126920e7f9ff18cdcef82dbff3e2f54ffa360243a17ac - md5: 18de09b20462742fe093ba39185d9bac - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/soupsieve?source=hash-mapping - size: 38187 - timestamp: 1769034509657 -- pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - name: spdx-headers - version: 1.5.1 - sha256: 73bcb1ed087824b55ccaa497d03d8f0f0b0eaf30e5f0f7d5bbd29d2c4fe78fcf +- pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl + name: tzlocal + version: 5.3.1 + sha256: eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d requires_dist: - - chardet>=5.2.0 - - requests>=2.32.3 - - black>=23.0.0 ; extra == 'dev' - - build>=0.10.0 ; extra == 'dev' - - hatch>=1.9.0 ; extra == 'dev' - - isort>=5.12.0 ; extra == 'dev' - - mypy>=1.0.0 ; extra == 'dev' - - pre-commit>=4.3.0 ; extra == 'dev' - - pytest-cov>=4.0.0 ; extra == 'dev' - - pytest>=7.0.0 ; extra == 'dev' - - ruff>=0.5.0 ; extra == 'dev' - - twine>=4.0.0 ; extra == 'dev' - - types-requests>=2.31.0.6 ; extra == 'dev' - - pytest-cov>=4.0.0 ; extra == 'test' - - pytest-mock>=3.10.0 ; extra == 'test' - - pytest>=7.0.0 ; extra == 'test' + - tzdata ; sys_platform == 'win32' + - pytest>=4.3 ; extra == 'devenv' + - pytest-mock>=3.3 ; extra == 'devenv' + - pytest-cov ; extra == 'devenv' + - check-manifest ; extra == 'devenv' + - zest-releaser ; extra == 'devenv' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/16/56/a31e8d3c9e8d21100b83bbe1c1f3f7c94db317393a229e193461e5e6d2a4/spglib-2.6.0-cp313-cp313-win_amd64.whl - name: spglib - version: 2.6.0 - sha256: ff1632524f6ac0031423474e48d6b69f4932ecb7eb4446a501f59619e2b5cbc9 +- pypi: https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: lxml + version: 6.1.0 + sha256: 363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c requires_dist: - - numpy>=1.20,<3 - - importlib-resources ; python_full_version < '3.10' - - typing-extensions>=4.9.0 ; python_full_version < '3.13' - - pytest ; extra == 'test' - - pyyaml ; extra == 'test' - - sphinx>=7.0 ; extra == 'docs' - - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c3/d9/a27997f84341fc0dfcdd1fe4179b6ba6c32a7aa880fdb8c514d4dad6fba3/h5py-3.16.0-cp313-cp313-win_amd64.whl + name: h5py + version: 3.16.0 + sha256: 18f2bbcd545e6991412253b98727374c356d67caa920e68dc79eab36bf5fedad + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c4/6d/82e65254354ba651dc966775270a9bbc02414a3eb3f1704e6c87dab2ea83/essdiffraction-26.5.1-py3-none-any.whl + name: essdiffraction + version: 26.5.1 + sha256: 8a6c779078c71be250714619214069221ab7968a69580d4e4d3f4b3e9a1a53ad + requires_dist: + - dask>=2022.1.0 + - essreduce>=26.4.0 + - graphviz + - numpy>=2 + - plopp>=26.2.0 + - pythreejs>=2.4.1 + - sciline>=25.4.1 + - scipp>=25.11.0 + - scippneutron>=26.3.0 + - scippnexus>=23.12.0 + - tof>=25.12.0 + - ncrystal[cif]>=4.1.0 + - spglib!=2.7 + - pandas>=2.1.2 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - pytest>=7.0 ; extra == 'test' + - ipywidgets>=8.1.7 ; extra == 'test' + - autodoc-pydantic ; extra == 'docs' + - ipykernel ; extra == 'docs' + - ipympl ; extra == 'docs' + - ipython!=8.7.0 ; extra == 'docs' + - myst-parser ; extra == 'docs' + - nbsphinx ; extra == 'docs' + - pandas ; extra == 'docs' + - pooch ; extra == 'docs' + - pydata-sphinx-theme>=0.14 ; extra == 'docs' + - sphinx ; extra == 'docs' - sphinx-autodoc-typehints ; extra == 'docs' - - myst-parser>=2.0 ; extra == 'docs' - - linkify-it-py ; extra == 'docs' - - sphinx-tippy ; extra == 'docs' - - spglib[test] ; extra == 'test-cov' - - pytest-cov ; extra == 'test-cov' - - spglib[test] ; extra == 'test-benchmark' - - pytest-benchmark ; extra == 'test-benchmark' - - spglib[test] ; extra == 'dev' - - pre-commit ; extra == 'dev' - - spglib[docs] ; extra == 'doc' - - spglib[test] ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2d/47/634fe8323c6c2bfa86e10eb41ebfe410db5e6231aa1727a31ce4f002480f/spglib-2.6.0-cp313-cp313-macosx_11_0_arm64.whl - name: spglib - version: 2.6.0 - sha256: 12db7a0d6ad84c55e61eda67590a438edeb48e57ffd5df868cd931b57fb8c630 + - sphinx-copybutton ; extra == 'docs' + - sphinx-design ; extra == 'docs' + - sphinxcontrib-bibtex ; extra == 'docs' + - pyarrow ; extra == 'docs' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: dbbd4aa20ca51e63b53bbde6a0fa4254b1aaabb74d2f542df7a7959feb1d760c + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl + name: matplotlib + version: 3.10.9 + sha256: f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7,<10 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + name: mkdocs-plugin-inline-svg + version: 0.1.0 + sha256: a5aab2d98a19b24019f8e650f54fc647c2f31e7d0e36fc5cf2d2161acc0ea49a requires_dist: - - numpy>=1.20,<3 - - importlib-resources ; python_full_version < '3.10' - - typing-extensions>=4.9.0 ; python_full_version < '3.13' - - pytest ; extra == 'test' - - pyyaml ; extra == 'test' - - sphinx>=7.0 ; extra == 'docs' - - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - myst-parser>=2.0 ; extra == 'docs' - - linkify-it-py ; extra == 'docs' - - sphinx-tippy ; extra == 'docs' - - spglib[test] ; extra == 'test-cov' - - pytest-cov ; extra == 'test-cov' - - spglib[test] ; extra == 'test-benchmark' - - pytest-benchmark ; extra == 'test-benchmark' - - spglib[test] ; extra == 'dev' - - pre-commit ; extra == 'dev' - - spglib[docs] ; extra == 'doc' - - spglib[test] ; extra == 'testing' + - mkdocs + requires_python: '>=3.5' +- pypi: https://files.pythonhosted.org/packages/c7/6b/6c02f55c2ce2f137ccca0986be7dd89bea31d5bee4346b4377fa3b8586df/ncrystal_core-4.4.2-py3-none-win_amd64.whl + name: ncrystal-core + version: 4.4.2 + sha256: 9b28a90b63849e6a3a807a0a59f7c2ee57e4c64f5643b2dcb6a798ac8ccf666a + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c7/a0/5ff05d1919ca249508012cad89f08fdc6cfbdaa15b41651c5fe6dffaf1d3/dfo_ls-1.6.5-py3-none-any.whl + name: dfo-ls + version: 1.6.5 + sha256: d147d42e471e240f9abf8bc38351a88f555ea6a8fcfd83119bbbf93c36f75ab2 + requires_dist: + - setuptools + - numpy + - scipy>=1.11 + - pandas + - pytest ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-rtd-theme ; extra == 'dev' + - trustregion>=1.1 ; extra == 'trustregion' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/53/01/1c0485ae02e645bc517bf5d5a6ca674f62c97e247890b954cbfe85c64dae/spglib-2.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: spglib - version: 2.6.0 - sha256: cc9d856d7cc936dc73b6b303aaf8b2fb4230a8527659373450c6e1139cbb2a5c +- pypi: https://files.pythonhosted.org/packages/c7/ea/7988934c8e3e3418aa043f70421817df28d06aef50bfd85f5ad3ec6e70f1/ncrystal_core-4.4.2-py3-none-macosx_11_0_arm64.whl + name: ncrystal-core + version: 4.4.2 + sha256: b7e6101a6850aa18cf441825214381614db444ffcba648de8266fe1c4d1024ce + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl + name: multidict + version: 6.7.1 + sha256: bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b requires_dist: - - numpy>=1.20,<3 - - importlib-resources ; python_full_version < '3.10' - - typing-extensions>=4.9.0 ; python_full_version < '3.13' - - pytest ; extra == 'test' - - pyyaml ; extra == 'test' - - sphinx>=7.0 ; extra == 'docs' - - sphinxcontrib-bibtex>=2.5 ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - myst-parser>=2.0 ; extra == 'docs' - - linkify-it-py ; extra == 'docs' - - sphinx-tippy ; extra == 'docs' - - spglib[test] ; extra == 'test-cov' - - pytest-cov ; extra == 'test-cov' - - spglib[test] ; extra == 'test-benchmark' - - pytest-benchmark ; extra == 'test-benchmark' - - spglib[test] ; extra == 'dev' - - pre-commit ; extra == 'dev' - - spglib[docs] ; extra == 'doc' - - spglib[test] ; extra == 'testing' + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/17/3a/7215b1b7d6d49dc9a87211be44562077f5f04f9bb5a59552c1c8e2d98173/sqlalchemy-2.0.49-cp313-cp313-win_amd64.whl - name: sqlalchemy - version: 2.0.49 - sha256: 12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 +- pypi: https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl + name: asn1crypto + version: 1.5.1 + sha256: db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 +- pypi: https://files.pythonhosted.org/packages/c9/b5/9302644225ba7dfa934a2ff2b9c7bb85701313a90dddb3dfaf693fa5bae2/backrefs-7.0-py311-none-any.whl + name: backrefs + version: '7.0' + sha256: a0fa7360c63509e9e077e174ef4e6d3c21c8db94189b9d957289ae6d794b9475 requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/ae/81/81755f50eb2478eaf2049728491d4ea4f416c1eb013338682173259efa09/sqlalchemy-2.0.49-cp313-cp313-macosx_11_0_arm64.whl - name: sqlalchemy - version: 2.0.49 - sha256: df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 + - regex ; extra == 'extras' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + name: pytest-xdist + version: 3.8.0 + sha256: 202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' + - execnet>=2.1 + - pytest>=7.0.0 + - filelock ; extra == 'testing' + - psutil>=3.0 ; extra == 'psutil' + - setproctitle ; extra == 'setproctitle' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + name: iniconfig + version: 2.3.0 + sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: fonttools + version: 4.62.1 + sha256: 1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cd/f5/038741f5e747a5f6ea3e72487211579d8cbea5eb9827a9cbd61d0108c4bd/sqlalchemy-2.0.49-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: sqlalchemy version: 2.0.49 @@ -12464,836 +12671,890 @@ packages: - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 - md5: b1b505328da7a6b246787df4b5a49fbc - depends: - - asttokens - - executing - - pure_eval - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/stack-data?source=hash-mapping - size: 26988 - timestamp: 1733569565672 -- pypi: https://files.pythonhosted.org/packages/56/5b/53ca0fd447f73423c7dc59d34e523530ef434481a3d18808ff7537ad33ec/svglib-1.5.1.tar.gz - name: svglib - version: 1.5.1 - sha256: 3ae765d3a9409ee60c0fb4d24c2deb6a80617aa927054f5bcd7fc98f0695e587 +- pypi: https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numpy + version: 2.4.4 + sha256: df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl + name: narwhals + version: 2.20.0 + sha256: 16e750ea5507d4ba6e8d03455b5f93a535e0405976561baea235bca5dc9f475d + requires_dist: + - cudf-cu12>=24.10.0 ; extra == 'cudf' + - dask[dataframe]>=2024.8 ; extra == 'dask' + - duckdb>=1.1 ; extra == 'duckdb' + - ibis-framework>=6.0.0 ; extra == 'ibis' + - packaging ; extra == 'ibis' + - pyarrow-hotfix ; extra == 'ibis' + - rich ; extra == 'ibis' + - modin ; extra == 'modin' + - pandas>=1.1.3 ; extra == 'pandas' + - polars>=0.20.4 ; extra == 'polars' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - pyspark>=3.5.0 ; extra == 'pyspark' + - pyspark[connect]>=3.5.0 ; extra == 'pyspark-connect' + - duckdb>=1.1 ; extra == 'sql' + - sqlparse ; extra == 'sql' + - sqlframe>=3.22.0,!=3.39.3 ; extra == 'sqlframe' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c requires_dist: - - reportlab - - lxml - - tinycss2>=0.6.0 - - cssselect2>=0.2.0 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/6d/93/01273a1b8d8454d45f2e18b3d6098c7be13a0864a55fbd0ebda7815c201a/svglib-1.6.0-py3-none-any.whl - name: svglib - version: 1.6.0 - sha256: 9aea8e2e81cbbf9c844460e4c7dc90e0a06aea7983bc201975ccd279d7b2d194 + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numpy + version: 2.4.4 + sha256: c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + name: mando + version: 0.7.1 + sha256: 26ef1d70928b6057ee3ca12583d73c63e05c49de8972d620c278a7b206581a8a requires_dist: - - cssselect2>=0.2.0 - - lxml>=6.0.0 - - reportlab>=4.4.3 - - rlpycairo>=0.4.0 - - tinycss2>=0.6.0 - - mypy>=1.18.1 ; extra == 'dev' - - pre-commit>=4.3.0 ; extra == 'dev' - - pytest-cov>=7.0.0 ; extra == 'dev' - - pytest-runner>=6.0.1 ; extra == 'dev' - - pytest>=8.3.5 ; extra == 'dev' - - ruff>=0.13.0 ; extra == 'dev' - - tox>=4.30.2 ; extra == 'dev' + - six + - argparse ; python_full_version < '2.7' + - funcsigs ; python_full_version < '3.3' + - rst2ansi ; extra == 'restructuredtext' +- pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: 6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl - name: sympy - version: 1.14.0 - sha256: e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5 +- pypi: https://files.pythonhosted.org/packages/d3/80/722402571443031989e87a5861f26f2e897778768906dff1f998b42f235d/diffpy_pdffit2-1.6.0-cp313-cp313-macosx_11_0_arm64.whl + name: diffpy-pdffit2 + version: 1.6.0 + sha256: 8837088196ddabd688deb77740c3f03ddc33f0df6964a8e3507701c32b67b8b2 requires_dist: - - mpmath>=1.1.0,<1.4 - - pytest>=7.1.0 ; extra == 'dev' - - hypothesis>=6.70.0 ; extra == 'dev' + - diffpy-structure + requires_python: '>=3.12,<3.15' +- pypi: https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl + name: fonttools + version: 4.62.1 + sha256: e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d4/06/19ff1efd58b85906149ce83dfddce23252cea5bec7e0fa5f834336cfe836/scipp-26.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 26.3.1 + sha256: ab5859a24b3150b588dd2c67e68b0c7f07c9444eae501f3b6326d6b4a34cbf10 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + name: pytest + version: 9.0.3 + sha256: 2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 + requires_dist: + - colorama>=0.4 ; sys_platform == 'win32' + - exceptiongroup>=1 ; python_full_version < '3.11' + - iniconfig>=1.0.1 + - packaging>=22 + - pluggy>=1.5,<2 + - pygments>=2.7.2 + - tomli>=1 ; python_full_version < '3.11' + - argcomplete ; extra == 'dev' + - attrs>=19.2 ; extra == 'dev' + - hypothesis>=3.56 ; extra == 'dev' + - mock ; extra == 'dev' + - requests ; extra == 'dev' + - setuptools ; extra == 'dev' + - xmlschema ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl + name: fsspec + version: 2026.4.0 + sha256: 11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 + requires_dist: + - adlfs ; extra == 'abfs' + - adlfs ; extra == 'adl' + - pyarrow>=1 ; extra == 'arrow' + - dask ; extra == 'dask' + - distributed ; extra == 'dask' + - pre-commit ; extra == 'dev' + - ruff>=0.5 ; extra == 'dev' + - numpydoc ; extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - yarl ; extra == 'doc' + - dropbox ; extra == 'dropbox' + - dropboxdrivefs ; extra == 'dropbox' + - requests ; extra == 'dropbox' + - adlfs ; extra == 'full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' + - dask ; extra == 'full' + - distributed ; extra == 'full' + - dropbox ; extra == 'full' + - dropboxdrivefs ; extra == 'full' + - fusepy ; extra == 'full' + - gcsfs>2024.2.0 ; extra == 'full' + - libarchive-c ; extra == 'full' + - ocifs ; extra == 'full' + - panel ; extra == 'full' + - paramiko ; extra == 'full' + - pyarrow>=1 ; extra == 'full' + - pygit2 ; extra == 'full' + - requests ; extra == 'full' + - s3fs>2024.2.0 ; extra == 'full' + - smbprotocol ; extra == 'full' + - tqdm ; extra == 'full' + - fusepy ; extra == 'fuse' + - gcsfs>2024.2.0 ; extra == 'gcs' + - pygit2 ; extra == 'git' + - requests ; extra == 'github' + - gcsfs ; extra == 'gs' + - panel ; extra == 'gui' + - pyarrow>=1 ; extra == 'hdfs' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' + - libarchive-c ; extra == 'libarchive' + - ocifs ; extra == 'oci' + - s3fs>2024.2.0 ; extra == 's3' + - paramiko ; extra == 'sftp' + - smbprotocol ; extra == 'smb' + - paramiko ; extra == 'ssh' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' + - numpy ; extra == 'test' + - pytest ; extra == 'test' + - pytest-asyncio!=0.22.0 ; extra == 'test' + - pytest-benchmark ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-recording ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - requests ; extra == 'test' + - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' + - dask[dataframe,test] ; extra == 'test-downstream' + - moto[server]>4,<5 ; extra == 'test-downstream' + - pytest-timeout ; extra == 'test-downstream' + - xarray ; extra == 'test-downstream' + - adlfs ; extra == 'test-full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' + - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' + - cloudpickle ; extra == 'test-full' + - dask ; extra == 'test-full' + - distributed ; extra == 'test-full' + - dropbox ; extra == 'test-full' + - dropboxdrivefs ; extra == 'test-full' + - fastparquet ; extra == 'test-full' + - fusepy ; extra == 'test-full' + - gcsfs ; extra == 'test-full' + - jinja2 ; extra == 'test-full' + - kerchunk ; extra == 'test-full' + - libarchive-c ; extra == 'test-full' + - lz4 ; extra == 'test-full' + - notebook ; extra == 'test-full' + - numpy ; extra == 'test-full' + - ocifs ; extra == 'test-full' + - pandas<3.0.0 ; extra == 'test-full' + - panel ; extra == 'test-full' + - paramiko ; extra == 'test-full' + - pyarrow ; extra == 'test-full' + - pyarrow>=1 ; extra == 'test-full' + - pyftpdlib ; extra == 'test-full' + - pygit2 ; extra == 'test-full' + - pytest ; extra == 'test-full' + - pytest-asyncio!=0.22.0 ; extra == 'test-full' + - pytest-benchmark ; extra == 'test-full' + - pytest-cov ; extra == 'test-full' + - pytest-mock ; extra == 'test-full' + - pytest-recording ; extra == 'test-full' + - pytest-rerunfailures ; extra == 'test-full' + - python-snappy ; extra == 'test-full' + - requests ; extra == 'test-full' + - smbprotocol ; extra == 'test-full' + - tqdm ; extra == 'test-full' + - urllib3 ; extra == 'test-full' + - zarr ; extra == 'test-full' + - zstandard ; python_full_version < '3.14' and extra == 'test-full' + - tqdm ; extra == 'tqdm' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl + name: trove-classifiers + version: 2026.4.28.13 + sha256: 8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 +- pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + name: pycodestyle + version: 2.14.0 + sha256: dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl - name: tabulate - version: 0.10.0 - sha256: f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3 - requires_dist: - - wcwidth ; extra == 'widechars' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh6dadd2b_1.conda - sha256: b375e8df0d5710717c31e7c8e93c025c37fa3504aea325c7a55509f64e5d4340 - md5: e43ca10d61e55d0a8ec5d8c62474ec9e - depends: - - __win - - pywinpty >=1.1.0 - - python >=3.10 - - tornado >=6.1.0 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/terminado?source=hash-mapping - size: 23665 - timestamp: 1766513806974 -- conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - sha256: 6b6727a13d1ca6a23de5e6686500d0669081a117736a87c8abf444d60c1e40eb - md5: 17b43cee5cc84969529d5d0b0309b2cb - depends: - - __unix - - ptyprocess - - python >=3.10 - - tornado >=6.1.0 - - python - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/terminado?source=hash-mapping - size: 24749 - timestamp: 1766513766867 -- conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - sha256: cad582d6f978276522f84bd209a5ddac824742fe2d452af6acf900f8650a73a2 - md5: f1acf5fdefa8300de697982bcb1761c9 - depends: - - python >=3.5 - - webencodings >=0.4 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/tinycss2?source=hash-mapping - size: 28285 - timestamp: 1729802975370 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac - md5: cffd3bdd58090148f4cfcd831f4b26ab - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - constrains: - - xorg-libx11 >=1.8.12,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3301196 - timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 - md5: a9d86bc62f39b94c4661716624eb21b0 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3127137 - timestamp: 1769460817696 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 - md5: 0481bfd9814bf525bd4b3ee4b51494c4 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: TCL - license_family: BSD - purls: [] - size: 3526350 - timestamp: 1769460339384 -- pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl - name: tof - version: 26.3.0 - sha256: e89783a072b05fdb53d9e76fbf919dc8935e75e118fdaf17ca5cc33727ef002b +- pypi: https://files.pythonhosted.org/packages/d8/8b/e2bbeb42068f0c48899e8eddd34902afc0f7429d4d2a152d2dc2670dc661/pythreejs-2.4.2-py3-none-any.whl + name: pythreejs + version: 2.4.2 + sha256: 8418807163ad91f4df53b58c4e991b26214852a1236f28f1afeaadf99d095818 requires_dist: - - plopp>=23.10.0 - - pooch>=1.5.0 - - scipp>=25.1.0 - - lazy-loader>=0.3 - - pytest>=8.0 ; extra == 'test' - - scippneutron>=24.12.0 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl - name: tokenize-rt - version: 6.2.0 - sha256: a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44 + - ipywidgets>=7.2.1 + - ipydatawidgets>=1.1.1 + - numpy + - traitlets + - sphinx>=1.5 ; extra == 'docs' + - nbsphinx>=0.2.13 ; extra == 'docs' + - nbsphinx-link ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - scipy ; extra == 'examples' + - matplotlib ; extra == 'examples' + - scikit-image ; extra == 'examples' + - ipywebrtc ; extra == 'examples' + - nbval ; extra == 'test' + - pytest-check-links ; extra == 'test' + - numpy>=1.14 ; extra == 'test' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + name: frozenlist + version: 1.8.0 + sha256: 878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - sha256: 91cafdb64268e43e0e10d30bd1bef5af392e69f00edd34dfaf909f69ab2da6bd - md5: b5325cf06a000c5b14970462ff5e4d58 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/tomli?source=hash-mapping - size: 21561 - timestamp: 1774492402955 -- pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - name: toolz - version: 1.1.0 - sha256: 15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 +- pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: 454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda - sha256: cd8bc08ca661291cfbb05581b79f7e6a6971a072a54a335abcea5460c1230880 - md5: 73b44a114241e564deb5846e7394bf19 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=compressed-mapping - size: 876817 - timestamp: 1774358035290 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda - sha256: 9e8497e1ecca77d03c6be2d3b5f901dfe0ab99686af4fb94ab418b7d449ac547 - md5: 6c0b0ae017b5bfd9c8d718217efd8f14 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 882996 - timestamp: 1774358035145 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py311hc949640_0.conda - sha256: 572923958ec987f3f68e228dfec243c89ab94b50398731215d36e2e040db8703 - md5: 6f12d9ff025ab1875dff67ad779ca29d - depends: - - __osx >=11.0 - - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - - python_abi 3.11.* *_cp311 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 875022 - timestamp: 1774358570256 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py313h0997733_0.conda - sha256: c5b0ee042d8a0b88a3823226dc95b794c042c498aee330aa9b4d78bfad01d099 - md5: 303333dd882dfeb303cc8bfac178464b - depends: - - __osx >=11.0 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 883472 - timestamp: 1774358832451 -- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda - sha256: 71f58fe09f7729ad82c8eb942e775ddeffcef454483911d19d1041ac5d81eec3 - md5: b004afcc680af88cb877978e71d42667 - depends: - - python >=3.11,<3.12.0a0 - - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 878544 - timestamp: 1774358187588 -- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py313h5ea7bf4_0.conda - sha256: b97fab804ab457cf4157103289317e3619e801a77410e756bb35c6223418cc6e - md5: 7d53f0d25ad5fd7d6962ce4eb385fb07 - depends: - - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 883689 - timestamp: 1774358224157 -- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - sha256: dfb681579be59c2e790c95f7f49b7529a9b0511d6385ad276e3c8988cbd54d2c - md5: 4bada6a6d908a27262af8ebddf4f7492 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - purls: - - pkg:pypi/traitlets?source=compressed-mapping - size: 115165 - timestamp: 1778074251714 -- pypi: https://files.pythonhosted.org/packages/8d/c0/fdf9d3ee103ce66a55f0532835ad5e154226c5222423c6636ba049dc42fc/traittypes-0.2.3-py2.py3-none-any.whl - name: traittypes - version: 0.2.3 - sha256: 49016082ce740d6556d9bb4672ee2d899cd14f9365f17cbb79d5d96b47096d4e +- pypi: https://files.pythonhosted.org/packages/db/09/a0ab6a246a7ede89e817d749a941df34f27a74bedf15551da51e86ae105e/pycairo-1.29.0-cp311-cp311-win_amd64.whl + name: pycairo + version: 1.29.0 + sha256: 3391532db03f9601c1cee9ebfa15b7d1db183c6020f3e75c1348cee16825934f + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + name: cfgv + version: 3.5.0 + sha256: a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl + name: locket + version: 1.0.0 + sha256: b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + name: watchdog + version: 6.0.0 + sha256: cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680 requires_dist: - - traitlets>=4.2.2 - - numpy ; extra == 'test' - - pandas ; extra == 'test' - - xarray ; extra == 'test' - - pytest ; extra == 'test' -- pypi: https://files.pythonhosted.org/packages/d6/bb/fbdc4e57731efb86b4209ffdd2519520782bf27b3c961beac3e5c20d2b87/trove_classifiers-2026.4.28.13-py3-none-any.whl - name: trove-classifiers - version: 2026.4.28.13 - sha256: 8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 -- pypi: https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl - name: typeguard - version: 4.5.1 - sha256: 44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl + name: xarray + version: 2026.4.0 + sha256: d43751d9fb4a90f9249c30431684f00c41bc874f1edccd862631a40cbc0edf08 + requires_dist: + - numpy>=1.26 + - packaging>=24.2 + - pandas>=2.2 + - scipy>=1.15 ; extra == 'accel' + - bottleneck ; extra == 'accel' + - numbagg>=0.9 ; extra == 'accel' + - numba>=0.62 ; extra == 'accel' + - flox>=0.10 ; extra == 'accel' + - opt-einsum ; extra == 'accel' + - xarray[accel,etc,io,parallel,viz] ; extra == 'complete' + - netcdf4>=1.6.0 ; extra == 'io' + - h5netcdf[h5py]>=1.5.0 ; extra == 'io' + - pydap ; extra == 'io' + - scipy>=1.15 ; extra == 'io' + - zarr>=3.0 ; extra == 'io' + - fsspec ; extra == 'io' + - cftime ; extra == 'io' + - pooch ; extra == 'io' + - sparse>=0.15 ; extra == 'etc' + - dask[complete] ; extra == 'parallel' + - cartopy>=0.24 ; extra == 'viz' + - matplotlib>=3.10 ; extra == 'viz' + - nc-time-axis ; extra == 'viz' + - seaborn ; extra == 'viz' + - pandas-stubs ; extra == 'types' + - scipy-stubs ; extra == 'types' + - types-colorama ; extra == 'types' + - types-decorator ; extra == 'types' + - types-defusedxml ; extra == 'types' + - types-docutils ; extra == 'types' + - types-networkx ; extra == 'types' + - types-openpyxl ; extra == 'types' + - types-pexpect ; extra == 'types' + - types-psutil ; extra == 'types' + - types-pycurl ; extra == 'types' + - types-pygments ; extra == 'types' + - types-python-dateutil ; extra == 'types' + - types-pytz ; extra == 'types' + - types-pyyaml ; extra == 'types' + - types-requests ; extra == 'types' + - types-setuptools ; extra == 'types' + - types-xlrd ; extra == 'types' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/dc/b7/901d837999a9350a7773289f7760cb473d4ba01fdc6ebae0ff2553d269ac/ncrystal_python-4.4.2-py3-none-any.whl + name: ncrystal-python + version: 4.4.2 + sha256: f419318d088fade6bcff1e39e15baf6fe69fcf5306dd681fca1106d1f63a89ce requires_dist: - - importlib-metadata>=3.6 ; python_full_version < '3.10' - - typing-extensions>=4.14.0 + - numpy>=1.22 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl - name: typer - version: 0.25.1 - sha256: 75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 +- pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + name: email-validator + version: 2.3.0 + sha256: 80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4 requires_dist: - - click>=8.2.1 - - shellingham>=1.3.0 - - rich>=13.8.0 - - annotated-doc>=0.0.2 + - dnspython>=2.0.0 + - idna>=2.0.0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + name: markdown + version: 3.10.2 + sha256: e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36 + requires_dist: + - coverage ; extra == 'testing' + - pyyaml ; extra == 'testing' + - mkdocs>=1.6 ; extra == 'docs' + - mkdocs-nature>=0.6 ; extra == 'docs' + - mdx-gh-links>=0.2 ; extra == 'docs' + - mkdocstrings[python]>=0.28.3 ; extra == 'docs' + - mkdocs-gen-files ; extra == 'docs' + - mkdocs-section-index ; extra == 'docs' + - mkdocs-literate-nav ; extra == 'docs' requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c - md5: edd329d7d3a4ab45dcf905899a7a6115 - depends: - - typing_extensions ==4.15.0 pyhcf101f3_0 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 91383 - timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda - sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a - md5: 53f5409c5cfd6c5a66417d68e3f0a864 - depends: - - python >=3.10 - - typing_extensions >=4.12.0 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/typing-inspection?source=compressed-mapping - size: 20935 - timestamp: 1777105465795 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 - md5: 0caa1af407ecff61170c9437a808404d - depends: - - python >=3.10 - - python - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/typing-extensions?source=hash-mapping - size: 51692 - timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda - sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c - md5: f6d7aa696c67756a650e91e15e88223c - depends: - - python >=3.9 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/typing-utils?source=hash-mapping - size: 15183 - timestamp: 1733331395943 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c - md5: ad659d0a2b3e47e38d829aa8cad2d610 - license: LicenseRef-Public-Domain - purls: [] - size: 119135 - timestamp: 1767016325805 -- pypi: https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl - name: tzlocal - version: 5.3.1 - sha256: eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d +- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + name: shellingham + version: 1.5.4 + sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: fonttools + version: 4.62.1 + sha256: 6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 requires_dist: - - tzdata ; sys_platform == 'win32' - - pytest>=4.3 ; extra == 'devenv' - - pytest-mock>=3.3 ; extra == 'devenv' - - pytest-cov ; extra == 'devenv' - - check-manifest ; extra == 'devenv' - - zest-releaser ; extra == 'devenv' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 - md5: 71b24316859acd00bdb8b38f5e2ce328 - constrains: - - vc14_runtime >=14.29.30037 - - vs2015_runtime >=14.29.30037 - license: LicenseRef-MicrosoftWindowsSDK10 - purls: [] - size: 694692 - timestamp: 1756385147981 -- pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - name: uncertainties - version: 3.2.3 - sha256: 313353900d8f88b283c9bad81e7d2b2d3d4bcc330cbace35403faaed7e78890a + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + name: plopp + version: 26.4.2 + sha256: 5cab99bb0905ce08a1d1d7d82f0f64cee7d594269ec1bd01a8a361bd14ab7bff requires_dist: - - numpy ; extra == 'arrays' + - lazy-loader>=0.4 + - matplotlib>=3.8 + - scipp>=25.8.0 ; extra == 'scipp' + - plopp[scipp] ; extra == 'all' + - ipympl>0.8.4 ; extra == 'all' + - pythreejs>=2.4.1 ; extra == 'all' + - mpltoolbox>=24.6.0 ; extra == 'all' + - ipywidgets>=8.1.0 ; extra == 'all' + - graphviz>=0.20.3 ; extra == 'all' + - plopp[scipp] ; extra == 'test' + - graphviz>=0.20.3 ; extra == 'test' + - h5py>=3.12 ; extra == 'test' + - ipympl>=0.8.4 ; extra == 'test' + - ipywidgets>=8.1.0 ; extra == 'test' + - ipykernel>=6.26,<7 ; extra == 'test' + - mpltoolbox>=24.6.0 ; extra == 'test' + - pandas>=2.2.2 ; extra == 'test' + - plotly>=5.15.0 ; extra == 'test' + - pooch>=1.5 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'test' + - pytest>=8.0 ; extra == 'test' + - pythreejs>=2.4.1 ; extra == 'test' + - scipy>=1.10.0 ; extra == 'test' + - xarray>=2024.5.0 ; extra == 'test' + - anywidget>=0.9.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + name: numpy + version: 2.4.4 + sha256: 4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + name: scipp + version: 26.3.1 + sha256: 37877cf07b4f54f224d5465c265d6a1e591d605d0c23dd350a4b48d95c26ab7b + requires_dist: + - numpy>=2 - pytest ; extra == 'test' - - pytest-codspeed ; extra == 'test' - - pytest-cov ; extra == 'test' - - scipy ; extra == 'test' - - sphinx ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - python-docs-theme ; extra == 'doc' - - uncertainties[arrays,doc,test] ; extra == 'all' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + name: cycler + version: 0.12.1 + sha256: 85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 + requires_dist: + - ipython ; extra == 'docs' + - matplotlib ; extra == 'docs' + - numpydoc ; extra == 'docs' + - sphinx ; extra == 'docs' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-xdist ; extra == 'tests' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - sha256: e0eb6c8daf892b3056f08416a96d68b0a358b7c46b99c8a50481b22631a4dfc0 - md5: e7cb0f5745e4c5035a460248334af7eb - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/uri-template?source=hash-mapping - size: 23990 - timestamp: 1733323714454 -- pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - name: uritools - version: 6.1.0 - sha256: f1b699052459711f1dd03721ca79341dc345054e6286f47313f8bce777782415 +- pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: pillow + version: 12.2.0 + sha256: e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a - md5: 9272daa869e03efe68833e3dc7a02130 - depends: - - backports.zstd >=1.0.0 - - brotli-python >=1.2.0 - - h2 >=4,<5 - - pysocks >=1.5.6,<2.0,!=1.5.7 - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/urllib3?source=hash-mapping - size: 103172 - timestamp: 1767817860341 -- pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl - name: validate-pyproject - version: '0.25' - sha256: f9d05e2686beff82f9ea954f582306b036ced3d3feb258c1110f2c2a495b1981 +- pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + name: nbmake + version: 1.5.5 + sha256: c6fbe6e48b60cacac14af40b38bf338a3b88f47f085c54ac5b8639ff0babaf4b requires_dist: - - fastjsonschema>=2.16.2,<=3 - - packaging>=24.2 ; extra == 'all' - - trove-classifiers>=2021.10.20 ; extra == 'all' - - tomli>=1.2.1 ; python_full_version < '3.11' and extra == 'all' - - validate-pyproject-schema-store ; extra == 'store' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a4/39/3a0ae5b0edb66e61bb0e8bc53a503495cba5892297ae21faf6ba0525e681/varname-1.0.0-py3-none-any.whl - name: varname - version: 1.0.0 - sha256: 1125bfe981c3bbbe56988f5cb85fdcd7cad923b153283c2d464aea8b4c833d51 + - ipykernel>=5.4.0 + - nbclient>=0.6.6 + - nbformat>=5.0.4 + - pygments>=2.7.3 + - pytest>=6.1.0 + requires_python: '>=3.8.0' +- pypi: https://files.pythonhosted.org/packages/ed/01/e1da2f721c3a8feec311a16924c42fb28c37445528df0747f47dec5232d5/crysfml-0.6.2-cp313-cp313-win_amd64.whl + name: crysfml + version: 0.6.2 + sha256: b32ddbf4010ce61a535182d58c12c410ed4a0f5de2259e7ef605e7fbcce40be3 requires_dist: - - executing>=2.1 - - typing-extensions>=4.13 ; python_full_version < '3.10' - - asttokens==3.* ; extra == 'all' - - pure-eval==0.* ; extra == 'all' + - numpy + requires_python: '>=3.11,<3.15' +- pypi: https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl + name: prettytable + version: 3.17.0 + sha256: aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287 + requires_dist: + - wcwidth + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-lazy-fixtures ; extra == 'tests' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ee/ab/7d7463cda94f8b68b969ea97aaad679655a0e436efd6a643e528a8de114e/gemmi-0.7.5-cp313-cp313-win_amd64.whl + name: gemmi + version: 0.7.5 + sha256: ad1f72ffa24adbfaf259e11471f6f071a668667f6ca846051f3bfea024fd337d requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a - md5: 1e610f2416b6acdd231c5f573d754a0f - depends: - - vc14_runtime >=14.44.35208 - track_features: - - vc14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 19356 - timestamp: 1767320221521 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 - md5: 37eb311485d2d8b2c419449582046a42 - depends: - - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_34 - constrains: - - vs2015_runtime 14.44.35208.* *_34 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 683233 - timestamp: 1767320219644 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 - md5: 242d9f25d2ae60c76b38a5e42858e51d - depends: - - ucrt >=10.0.20348.0 - constrains: - - vs2015_runtime 14.44.35208.* *_34 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 115235 - timestamp: 1767320173250 -- pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl - name: versioningit - version: 3.3.0 - sha256: 23b1db3c4756cded9bd6b0ddec6643c261e3d0c471707da3e0b230b81ce53e4b +- pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: lxml + version: 6.1.0 + sha256: e69aa6805905807186eb00e66c6d97a935c928275182eb02ee40ba00da9623b2 requires_dist: - - importlib-metadata>=3.6 ; python_full_version < '3.10' - - packaging>=17.1 - - tomli>=1.2,<3.0 ; python_full_version < '3.11' + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl - name: verspec - version: 0.1.0 - sha256: 741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 - requires_dist: - - coverage ; extra == 'test' - - flake8>=3.7 ; extra == 'test' - - mypy ; extra == 'test' - - pretend ; extra == 'test' - - pytest ; extra == 'test' -- pypi: https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl - name: virtualenv - version: 21.3.1 - sha256: d1a71cf58f2f9228fff23a1f6ec15d39785c6b32e03658d104974247145edd35 +- pypi: https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.5 + sha256: 3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665 requires_dist: - - distlib>=0.3.7,<1 - - filelock>=3.24.2,<4 ; python_full_version >= '3.10' - - filelock>=3.16.1,<=3.19.1 ; python_full_version < '3.10' - - importlib-metadata>=6.6 ; python_full_version < '3.8' - - platformdirs>=3.9.1,<5 - - python-discovery>=1.2.2 - - typing-extensions>=4.13.2 ; python_full_version < '3.11' + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f1/2c/3850985d4c64048dec7b826f8a803e135b52b11b4c81c9cd4326b1ca15ab/ncrystal_core-4.4.2-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: ncrystal-core + version: 4.4.2 + sha256: d0d9c47cd017b7cefc52dde50546d7c151bfdd75d345e42e2b3e74ab5fe83c62 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl - name: watchdog - version: 6.0.0 - sha256: 20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2 +- pypi: https://files.pythonhosted.org/packages/f1/5b/e63c877c4c94382b66de5045e08ec8cd960e8a4d22f0d62a4dfb1f9e5ac6/ipydatawidgets-4.3.5-py2.py3-none-any.whl + name: ipydatawidgets + version: 4.3.5 + sha256: d590cdb7c364f2f6ab346f20b9d2dd661d27a834ef7845bc9d7113118f05ec87 requires_dist: - - pyyaml>=3.10 ; extra == 'watchmedo' + - ipywidgets>=7.0.0 + - numpy + - traittypes>=0.2.0 + - sphinx ; extra == 'docs' + - recommonmark ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - pytest>=4 ; extra == 'test' + - pytest-cov ; extra == 'test' + - nbval>=0.9.2 ; extra == 'test' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: propcache + version: 0.4.1 + sha256: d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl - name: watchdog - version: 6.0.0 - sha256: afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c +- pypi: https://files.pythonhosted.org/packages/f2/f2/728f041460f1b9739b85ee23b45fa5a505962ea11fd85bdbe2a02b021373/darkdetect-0.8.0-py3-none-any.whl + name: darkdetect + version: 0.8.0 + sha256: a7509ccf517eaad92b31c214f593dbcf138ea8a43b2935406bbd565e15527a85 + requires_dist: + - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'macos-listener' + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + name: propcache + version: 0.4.1 + sha256: 364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl + name: pyhanko-certvalidator + version: 0.31.1 + sha256: 0aabe25b536ed555f3b18e5eb2c62ff46adeff9d15e27f0c9d5d81952d956f45 requires_dist: - - pyyaml>=3.10 ; extra == 'watchmedo' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl - name: watchdog - version: 6.0.0 - sha256: cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680 + - asn1crypto>=1.5.1 + - oscrypto>=1.1.0 + - cryptography>=48.0.0 + - uritools>=3.0.1 + - requests>=2.31.0 + - aiohttp>=3.9,<3.14 ; extra == 'async-http' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f4/a4/61adb19f3c74b0dc0e411de4f06ebef564b1f179928f9dffcbd4b378f2ef/jupyter_notebook_parser-0.1.4-py2.py3-none-any.whl + name: jupyter-notebook-parser + version: 0.1.4 + sha256: 27b3b67cf898684e646d569f017cb27046774ad23866cb0bdf51d5f76a46476b + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/f5/57/2a154a69d6642860300bf8eb205d13131104991f2b1065bbb9075ac5c32e/tof-26.3.0-py3-none-any.whl + name: tof + version: 26.3.0 + sha256: e89783a072b05fdb53d9e76fbf919dc8935e75e118fdaf17ca5cc33727ef002b requires_dist: - - pyyaml>=3.10 ; extra == 'watchmedo' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl - name: watchdog - version: 6.0.0 - sha256: a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b + - plopp>=23.10.0 + - pooch>=1.5.0 + - scipp>=25.1.0 + - lazy-loader>=0.3 + - pytest>=8.0 ; extra == 'test' + - scippneutron>=24.12.0 ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 requires_dist: - - pyyaml>=3.10 ; extra == 'watchmedo' + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + name: propcache + version: 0.4.1 + sha256: 381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - sha256: 1ee2d8384972ecbf8630ce8a3ea9d16858358ad3e8566675295e66996d5352da - md5: eb9538b8e55069434a18547f43b96059 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/wcwidth?source=compressed-mapping - size: 82917 - timestamp: 1777744489106 -- conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 - md5: 6639b6b0d8b5a284f027a2003669aa65 - depends: - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/webcolors?source=hash-mapping - size: 18987 - timestamp: 1761899393153 -- conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - sha256: 19ff205e138bb056a46f9e3839935a2e60bd1cf01c8241a5e172a422fed4f9c6 - md5: 2841eb5bfc75ce15e9a0054b98dcd64d - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/webencodings?source=hash-mapping - size: 15496 - timestamp: 1733236131358 -- conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - sha256: 42a2b61e393e61cdf75ced1f5f324a64af25f347d16c60b14117393a98656397 - md5: 2f1ed718fcd829c184a6d4f0f2e07409 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/websocket-client?source=hash-mapping - size: 61391 - timestamp: 1759928175142 -- pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - name: widgetsnbextension - version: 4.0.15 - sha256: 8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda - sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f - md5: 46e441ba871f524e2b067929da3051c2 - depends: - - __win - - python >=3.9 - license: LicenseRef-Public-Domain - purls: - - pkg:pypi/win-inet-pton?source=hash-mapping - size: 9555 - timestamp: 1733130678956 -- conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - sha256: 9df10c5b607dd30e05ba08cbd940009305c75db242476f4e845ea06008b0a283 - md5: 1cee351bf20b830d991dbe0bc8cd7dfe - license: MIT - license_family: MIT - purls: [] - size: 1176306 -- pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - name: wsproto - version: 1.3.2 - sha256: 61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584 +- pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + name: py + version: 1.11.0 + sha256: 607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl + name: ncrystal + version: 4.4.2 + sha256: e02fa7d743addc3fbea23287737a88b8d01192450fdca51554d3f9032fe4617c requires_dist: - - h11>=0.16.0,<1 + - ncrystal-core==4.4.2 + - ncrystal-python==4.4.2 + - spglib>=2.1.0 ; extra == 'composer' + - ase>=3.23.0 ; extra == 'cif' + - gemmi>=0.6.1 ; extra == 'cif' + - spglib>=2.1.0 ; extra == 'cif' + - endf-parserpy>=0.14.3 ; extra == 'endf' + - matplotlib>=3.6.0 ; extra == 'plot' + - ase>=3.23.0 ; extra == 'all' + - endf-parserpy>=0.14.3 ; extra == 'all' + - gemmi>=0.6.1 ; extra == 'all' + - matplotlib>=3.6.0 ; extra == 'all' + - spglib>=2.1.0 ; extra == 'all' + - pyyaml>=6.0.0 ; extra == 'devel' + - ase>=3.23.0 ; extra == 'devel' + - cppcheck ; extra == 'devel' + - endf-parserpy>=0.14.3 ; extra == 'devel' + - gemmi>=0.6.1 ; extra == 'devel' + - matplotlib>=3.6.0 ; extra == 'devel' + - mpmath>=1.3.0 ; extra == 'devel' + - numpy>=1.22 ; extra == 'devel' + - pybind11>=2.11.0 ; extra == 'devel' + - ruff>=0.8.1 ; extra == 'devel' + - simple-build-system>=1.6.0 ; extra == 'devel' + - spglib>=2.1.0 ; extra == 'devel' + - tomli>=2.0.0 ; python_full_version < '3.11' and extra == 'devel' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/f7/20/e6c0ff62ca2ad1a396a34f4380bafccaaf8791ff8fccf3d995a1fc12d417/h5py-3.16.0-cp311-cp311-win_amd64.whl + name: h5py + version: 3.16.0 + sha256: 17d1f1630f92ad74494a9a7392ab25982ce2b469fc62da6074c0ce48366a2999 + requires_dist: + - numpy>=1.21.2 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/93/ca/d53764f0534ff857239595f090f4cb83b599d226cc326c7de5eb3d802715/xhtml2pdf-0.2.17-py3-none-any.whl - name: xhtml2pdf - version: 0.2.17 - sha256: 61a7ecac829fed518f7dbcb916e9d56bea6e521e02e54644b3d0ca33f0658315 +- pypi: https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl + name: pymdown-extensions + version: 10.21.2 + sha256: 5c0fd2a2bea14eb39af8ff284f1066d898ab2187d81b889b75d46d4348c01638 requires_dist: - - arabic-reshaper>=3.0.0 - - html5lib>=1.1 - - pillow>=8.1.1 - - pyhanko>=0.12.1 - - pyhanko-certvalidator>=0.19.5 - - pypdf>=3.1.0 - - python-bidi>=0.5.0 - - reportlab>=4.0.4,<5 - - svglib>=1.2.1 - - reportlab[pycairo]>=4.0.4,<5 ; extra == 'pycairo' - - reportlab[renderpm]>=4.0.4,<5 ; extra == 'renderpm' - - tomli>=2.0.1 ; python_full_version < '3.11' and extra == 'test' - - tox ; extra == 'test' - - coverage>=5.3 ; extra == 'test' - - sphinx>=6 ; extra == 'docs' - - sphinx-rtd-theme>=0.5.0 ; extra == 'docs' - - sphinx-reredirects>=0.1.3 ; extra == 'docs' - - build ; extra == 'release' - - twine ; extra == 'release' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/38/8b/7ec325b4e9e78beefc2d025b01ee8a2fde771ef7c957c3bff99b9e1fbffa/xraydb-4.5.8-py3-none-any.whl - name: xraydb - version: 4.5.8 - sha256: 2215baafa6a03d00d0254a94525aafc6493c8c285e4ac4477fbd6271b25e6a51 + - markdown>=3.6 + - pyyaml + - pygments>=2.19.1 ; extra == 'extra' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + name: ghp-import + version: 2.1.0 + sha256: 8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 requires_dist: - - numpy>=1.19 - - scipy>=1.6 - - sqlalchemy>=2.0.1 - - platformdirs - - build ; extra == 'dev' + - python-dateutil>=2.8.1 - twine ; extra == 'dev' - - sphinx ; extra == 'doc' + - markdown ; extra == 'dev' + - flake8 ; extra == 'dev' + - wheel ; extra == 'dev' +- pypi: https://files.pythonhosted.org/packages/f7/ee/d0348d8dd27ac7f001e9583c004f1b245826b04cc23b5ce6b7867c4a1cc6/refnx-0.1.63-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: refnx + version: 0.1.63 + sha256: 4f397b0d6e18ac1bb793372ec92c9f4a122383387a706dea456df5a2c90dff5e + requires_dist: + - numpy>=2.0 + - scipy + - orsopy + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - traitlets ; extra == 'all' + - matplotlib ; extra == 'all' + - xlrd ; extra == 'all' + - h5py ; extra == 'all' + - jupyter ; extra == 'all' + - tqdm ; extra == 'all' + - pymc ; extra == 'all' + - pytensor ; extra == 'all' + - attrs ; extra == 'all' + - pandas ; extra == 'all' + - pyparsing ; extra == 'all' + - periodictable ; extra == 'all' + - pyqt6 ; extra == 'all' + - qtpy ; extra == 'all' + - corner ; extra == 'all' + - numba ; extra == 'all' - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - coverage ; extra == 'test' - - xraydb[dev,doc,test] ; extra == 'all' + - uncertainties ; extra == 'test' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl + name: toolz + version: 1.1.0 + sha256: 15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8 requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad - md5: a77f85f77be52ff59391544bfe73390a - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: MIT - license_family: MIT - purls: [] - size: 85189 - timestamp: 1753484064210 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac - md5: 78a0fe9e9c50d2c381e8ee47e3ea437d - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 83386 - timestamp: 1753484079473 -- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 - md5: 433699cba6602098ae8957a323da2664 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 63944 - timestamp: 1753484092156 -- pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: yarl - version: 1.23.0 - sha256: 34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 +- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + name: aiosignal + version: 1.4.0 + sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl - name: yarl - version: 1.23.0 - sha256: baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 + - frozenlist>=1.1.0 + - typing-extensions>=4.2 ; python_full_version < '3.13' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + name: mdit-py-plugins + version: 0.5.0 + sha256: 07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 + - markdown-it-py>=2.0.0,<5.0.0 + - pre-commit ; extra == 'code-style' + - myst-parser ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl - name: yarl - version: 1.23.0 - sha256: bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 +- pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl + name: refl1d + version: 1.0.1 + sha256: 8cc52121790df465e3a659d0fb0298f2501256c6f2d7fca26085927297112eb1 requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 + - bumps==1.0.4 + - matplotlib + - numba + - numpy + - periodictable + - scipy + - orsopy + - ipython ; extra == 'dev' + - matplotlib ; extra == 'dev' + - nbsphinx ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydantic ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - sphinx<8.2 ; extra == 'dev' + - versioningit ; extra == 'dev' + - wxpython ; extra == 'full' + - ipython ; extra == 'full' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: yarl - version: 1.23.0 - sha256: 99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 - requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 +- pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl + name: uritools + version: 6.1.0 + sha256: f1b699052459711f1dd03721ca79341dc345054e6286f47313f8bce777782415 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl - name: yarl - version: 1.23.0 - sha256: 7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b +- pypi: https://files.pythonhosted.org/packages/fd/a5/03c970d57f4c1741354837353ce39fb5206952ae1dba8922d29c86f64805/numba-0.65.1-cp313-cp313-win_amd64.whl + name: numba + version: 0.65.1 + sha256: 85be74c0d036842699a30058f82fb88fc5ffdc59f7615cab5792ea92914c9b62 requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 + - llvmlite>=0.47.0.dev0,<0.48 + - numpy>=1.22 + - numpy>=1.22,<2.5 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl - name: yarl - version: 1.23.0 - sha256: dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 +- pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda - sha256: 325d370b28e2b9cc1f765c5b4cdb394c91a5d958fbd15da1a14607a28fee09f6 - md5: 755b096086851e1193f3b10347415d7c - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - krb5 >=1.22.2,<1.23.0a0 - - libsodium >=1.0.21,<1.0.22.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 311150 - timestamp: 1772476812121 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - sha256: 2705360c72d4db8de34291493379ffd13b09fd594d0af20c9eefa8a3f060d868 - md5: e85dcd3bde2b10081cdcaeae15797506 - depends: - - __osx >=11.0 - - libcxx >=19 - - krb5 >=1.22.2,<1.23.0a0 - - libsodium >=1.0.21,<1.0.22.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 245246 - timestamp: 1772476886668 -- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - sha256: b8568dfde46edf3455458912ea6ffb760e4456db8230a0cf34ecbc557d3c275f - md5: 1ab0237036bfb14e923d6107473b0021 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libsodium >=1.0.21,<1.0.22.0a0 - - krb5 >=1.22.2,<1.23.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 265665 - timestamp: 1772476832995 -- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - sha256: 523616c0530d305d2216c2b4a8dfd3872628b60083255b89c5e0d8c42e738cca - md5: e1c36c6121a7c9c76f2f148f1e83b983 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/zipp?source=compressed-mapping - size: 24461 - timestamp: 1776131454755 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 - md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 - depends: - - __glibc >=2.17,<3.0.a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 601375 - timestamp: 1764777111296 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 - md5: ab136e4c34e97f34fb621d2592a393d8 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 433413 - timestamp: 1764777166076 -- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 - md5: 053b84beec00b71ea8ff7a4f84b55207 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 388453 - timestamp: 1764777142545 + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' diff --git a/pyproject.toml b/pyproject.toml index 681c5562..e9a7c354 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,8 @@ classifiers = [ ] requires-python = '>=3.11' dependencies = [ - 'easyscience', + 'easyscience @ git+https://github.com/easyscience/corelib.git@develop', + # 'easyscience', 'scipp', 'refnx', 'refl1d>=1.0.0', @@ -68,6 +69,8 @@ dev = [ 'mkdocstrings-python', # MkDocs: Python docstring support 'pyyaml', # YAML parser 'spdx-headers', # SPDX license header validation + 'arviz', # Bayesian analysis and visualization + 'plotly', # Interactive plotting ] [project.urls] diff --git a/src/easyreflectometry/__init__.py b/src/easyreflectometry/__init__.py index 8ff945d0..a18fee06 100644 --- a/src/easyreflectometry/__init__.py +++ b/src/easyreflectometry/__init__.py @@ -5,6 +5,7 @@ from importlib import metadata +from .analysis.bayesian import PosteriorResults from .project import Project try: @@ -14,5 +15,6 @@ __all__ = [ 'Project', + 'PosteriorResults', '__version__', ] diff --git a/src/easyreflectometry/analysis/__init__.py b/src/easyreflectometry/analysis/__init__.py new file mode 100644 index 00000000..9f086835 --- /dev/null +++ b/src/easyreflectometry/analysis/__init__.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2026 EasyReflectometry contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Post-hoc analysis utilities for reflectometry fitting results.""" + +from easyreflectometry.analysis.bayesian import PosteriorResults +from easyreflectometry.analysis.bayesian import credible_intervals +from easyreflectometry.analysis.bayesian import plot_corner +from easyreflectometry.analysis.bayesian import plot_distribution +from easyreflectometry.analysis.bayesian import plot_trace +from easyreflectometry.analysis.bayesian import posterior_predictive_reflectivity +from easyreflectometry.analysis.bayesian import posterior_predictive_sld_profile +from easyreflectometry.analysis.bayesian import posterior_summary + +__all__ = [ + 'PosteriorResults', + 'plot_corner', + 'plot_distribution', + 'plot_trace', + 'posterior_summary', + 'credible_intervals', + 'posterior_predictive_reflectivity', + 'posterior_predictive_sld_profile', +] diff --git a/src/easyreflectometry/analysis/bayesian.py b/src/easyreflectometry/analysis/bayesian.py new file mode 100644 index 00000000..39389a84 --- /dev/null +++ b/src/easyreflectometry/analysis/bayesian.py @@ -0,0 +1,1376 @@ +# SPDX-FileCopyrightText: 2026 EasyReflectometry contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Bayesian posterior analysis for reflectometry fitting results.""" + +from __future__ import annotations + +import hashlib +import json +import warnings +from typing import Any + +import numpy as np +from easyscience.fitting.minimizers.minimizer_base import MINIMIZER_PARAMETER_PREFIX + +try: + import arviz as _arviz + + _HAS_ARVIZ = True +except ImportError: + _HAS_ARVIZ = False + + +def _require_arviz(): + if not _HAS_ARVIZ: + raise ImportError('The ``arviz`` library is required for trace plots and R-hat. Install it with ``pip install arviz``.') + + +def _require_plotly(): + try: + import plotly # noqa: F401 + except ImportError as exc: + raise ImportError( + 'The ``plotly`` library is required for posterior plots. Install it with ``pip install plotly``.' + ) from exc + + +def _wrap_pair_label(name: str, max_len: int = 16) -> str: + """Insert ``
`` line breaks so long parameter labels don't overlap. + + Dotted names (e.g. ``layer1.thickness``) break on dots; plain names + word-wrap on spaces at roughly *max_len* characters per line. + """ + name = name.strip() + if not name: + return name + if '.' in name: + parts = [p.strip() for p in name.split('.') if p.strip()] + if parts: + return '
'.join([*(f'{p}.' for p in parts[:-1]), parts[-1]]) + if len(name) <= max_len: + return name + words = name.split() + if len(words) == 1: + return name + lines: list[str] = [] + current = '' + for word in words: + if current and len(current) + 1 + len(word) > max_len: + lines.append(current) + current = word + else: + current = f'{current} {word}' if current else word + if current: + lines.append(current) + return '
'.join(lines) + + +def _to_arviz_data(draws: np.ndarray, param_names: list[str]): + """Convert posterior draws to an arviz InferenceData object. + + :param draws: Posterior samples, shape ``(n_samples, n_params)`` or + ``(n_chains, n_draws, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :return: arviz InferenceData object. + """ + draws = np.asarray(draws, dtype=np.float64) + if draws.ndim == 2: + draws = draws[np.newaxis, ...] # (1, n_samples, n_params) + + # Build a dict of {param_name: (chain, draw) array} + posterior_dict = {} + for i, name in enumerate(param_names): + posterior_dict[name] = draws[:, :, i] + + return _arviz.from_dict({'posterior': posterior_dict}) + + +class PosteriorResults: + """Container for Bayesian posterior samples with analysis methods. + + :param draws: Posterior samples, shape ``(n_samples, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column of ``draws``). + :type param_names: list[str] + :param logp: Log-posterior values, shape ``(n_samples,)``, or ``None``. + :type logp: np.ndarray | None + :param sampler_state: Raw sampler state object (e.g. BUMPS ``DreamState``), or ``None``. + :type sampler_state: Any | None + """ + + def __init__( + self, + draws: np.ndarray, + param_names: list[str], + logp: np.ndarray | None = None, + sampler_state: Any | None = None, + ): + self.draws = np.asarray(draws) + self.param_names = list(param_names) + self.logp = np.asarray(logp) if logp is not None else None + self.sampler_state = sampler_state + + def __repr__(self) -> str: + n_samples, n_params = self.draws.shape + return f'PosteriorResults(n_samples={n_samples}, n_params={n_params}, param_names={self.param_names})' + + def summary(self) -> str: + """Return a formatted summary table with mean, sd, and equal-tailed 95% credible interval for each parameter. + + :return: Formatted summary table as a string. + :rtype: str + """ + return posterior_summary(self.draws, self.param_names) + + def corner(self) -> Any: + """Return the parameter-correlation corner plot as a Plotly Figure. + + Requires the ``plotly`` library. + + :return: Plotly Figure. + """ + return plot_corner(self.draws, self.param_names) + + def trace(self, **kwargs) -> None: + """Plot MCMC trace plot. + + Requires the ``arviz`` library. + + :param kwargs: Additional keyword arguments passed to ``arviz.plot_trace``. + """ + plot_trace(self.draws, self.param_names, **kwargs) + + def distribution(self) -> Any: + """Return the per-parameter marginal posterior distributions as a Plotly Figure. + + Each panel overlays the posterior histogram, a smooth KDE marginal, the + 95% credible interval, the median, and the best posterior sample (when + ``logp`` is available). Requires the ``plotly`` library. + + :return: Plotly Figure. + """ + return plot_distribution(self.draws, self.param_names, logp=self.logp, return_figure=True) + + def credible_interval(self, alpha: float = 0.95) -> dict: + """Compute equal-tailed credible intervals for each parameter. + + :param alpha: Credible interval width (e.g. 0.95 for 95%). + :type alpha: float + :return: Dictionary mapping parameter name to ``(lower, upper)``. + :rtype: dict + """ + return credible_intervals(self.draws, self.param_names, alpha=alpha) + + def save(self, path: str) -> None: + """Persist this posterior trace to disk. + + Convenience wrapper around :func:`save_posterior`. + + :param path: File path prefix (see :func:`save_posterior`). + :type path: str + """ + save_posterior(self, path) + + def gelman_rubin(self) -> dict | None: + """Compute the Gelman-Rubin R-hat convergence diagnostic. + + Requires the ``arviz`` library and posterior draws with at least + two chains, i.e. shape ``(n_chains, n_draws, n_params)`` with + ``n_chains >= 2``. R-hat is undefined for a single chain. + + :return: Dictionary mapping parameter name to R-hat value, or ``None`` + if ``arviz`` is not available. + :rtype: dict | None + :raises ValueError: If ``self.draws`` does not contain at least two + chains. + """ + if not _HAS_ARVIZ: + warnings.warn( + 'The ``arviz`` library is required for Gelman-Rubin R-hat. Install it with ``pip install arviz``.', + UserWarning, + ) + return None + if self.draws.ndim < 3 or self.draws.shape[0] < 2: + raise ValueError( + 'Gelman-Rubin R-hat requires posterior draws with at least 2 chains ' + '(shape ``(n_chains, n_draws, n_params)`` with ``n_chains >= 2``).' + ) + data = _to_arviz_data(self.draws, self.param_names) + rhat = _arviz.rhat(data) + return {name: float(rhat[name].values) for name in self.param_names} + + +def posterior_summary(draws: np.ndarray, param_names: list[str]) -> str: + """Return a formatted summary table with mean, sd, and the equal-tailed + 2.5%/97.5% posterior quantiles for each parameter. + + The reported interval is the equal-tailed 95% credible interval; it is + not a highest-density interval (HDI) and the two coincide only for + symmetric unimodal posteriors. + + :param draws: Posterior samples, shape ``(n_samples, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :return: Formatted summary table as a string. + :rtype: str + """ + draws = np.asarray(draws) + lines = [f'{"parameter":<30s} {"mean":>10s} {"sd":>10s} {"q2.5%":>10s} {"q97.5%":>10s}'] + for i, name in enumerate(param_names): + col = draws[:, i] + lo, hi = np.percentile(col, [2.5, 97.5]) + lines.append(f'{name:<30s} {col.mean():>10.4f} {col.std():>10.4f} {lo:>10.4f} {hi:>10.4f}') + return '\n'.join(lines) + + +# Posterior pair-plot palette and styling, mirroring easydiffraction so the +# corner plots match across the two libraries. +_POSTERIOR_PAIR_MIN_SAMPLE_COUNT = 2 +_POSTERIOR_PAIR_COVARIANCE_RANK = 2 +_POSTERIOR_PAIR_SCATTER_MAX_POINTS = 1500 +_POSTERIOR_PAIR_CONTOUR_GRID_SIZE = 80 +_POSTERIOR_PAIR_DENSITY_GRID_SIZE = 256 + +_POSTERIOR_PAIR_MARGINAL_LINE_COLOR = 'rgb(44, 160, 44)' +_POSTERIOR_PAIR_MARGINAL_FILL_COLOR = 'rgba(44, 160, 44, 0.22)' +_POSTERIOR_PAIR_SCATTER_COLOR = 'rgba(140, 140, 140, 0.22)' +_POSTERIOR_HISTOGRAM_FILL_COLOR = 'rgba(120, 120, 120, 0.38)' +_POSTERIOR_HISTOGRAM_LINE_COLOR = 'rgba(120, 120, 120, 0.24)' +_POSTERIOR_INTERVAL_95_FILL_COLOR = 'rgba(214, 39, 40, 0.14)' +_POSTERIOR_MEDIAN_LINE_COLOR = 'rgb(80, 80, 80)' +_POSTERIOR_POINT_ESTIMATE_LINE_COLOR = 'rgb(214, 39, 40)' +_POSTERIOR_CONTOUR_FILL_COLORSCALE = [ + [0.0, 'rgba(224, 233, 255, 0.62)'], + [0.35, 'rgba(183, 203, 255, 0.70)'], + [0.60, 'rgba(138, 169, 252, 0.78)'], + [0.82, 'rgba(96, 131, 242, 0.84)'], + [1.0, 'rgba(58, 86, 224, 0.90)'], +] +_POSTERIOR_NEGATIVE_CONTOUR_FILL_COLORSCALE = [ + [0.0, 'rgba(255, 224, 224, 0.62)'], + [0.35, 'rgba(250, 188, 188, 0.70)'], + [0.60, 'rgba(245, 148, 148, 0.78)'], + [0.82, 'rgba(237, 104, 104, 0.84)'], + [1.0, 'rgba(215, 48, 39, 0.90)'], +] +_POSTERIOR_CONTOUR_LINE_COLORSCALE = [ + [0.0, 'rgba(183, 203, 255, 0.94)'], + [0.35, 'rgba(183, 203, 255, 0.94)'], + [0.35, 'rgba(138, 169, 252, 0.95)'], + [0.60, 'rgba(138, 169, 252, 0.95)'], + [0.60, 'rgba(96, 131, 242, 0.96)'], + [0.82, 'rgba(96, 131, 242, 0.96)'], + [0.82, 'rgba(58, 86, 224, 0.98)'], + [1.0, 'rgba(58, 86, 224, 0.98)'], +] +_POSTERIOR_NEGATIVE_CONTOUR_LINE_COLORSCALE = [ + [0.0, 'rgba(250, 188, 188, 0.94)'], + [0.35, 'rgba(250, 188, 188, 0.94)'], + [0.35, 'rgba(245, 148, 148, 0.95)'], + [0.60, 'rgba(245, 148, 148, 0.95)'], + [0.60, 'rgba(237, 104, 104, 0.96)'], + [0.82, 'rgba(237, 104, 104, 0.96)'], + [0.82, 'rgba(215, 48, 39, 0.98)'], + [1.0, 'rgba(215, 48, 39, 0.98)'], +] + + +def _posterior_axis_bounds(values: np.ndarray) -> tuple[float, float] | None: + """Return padded ``(lower, upper)`` plotting bounds for one posterior axis. + + :param values: Posterior samples for a single parameter. + :type values: np.ndarray + :return: Padded bounds, or ``None`` if there are no finite samples. + :rtype: tuple[float, float] | None + """ + data = np.asarray(values, dtype=float) + data = data[np.isfinite(data)] + if data.size == 0: + return None + data_min = float(np.min(data)) + data_max = float(np.max(data)) + data_range = data_max - data_min + padding = 0.05 * data_range if data_range > 0 else max(abs(data_min), 1.0) * 0.05 + if padding == 0: + padding = 1e-6 + return data_min - padding, data_max + padding + + +def _posterior_density_curve( + values: np.ndarray, + grid_size: int = _POSTERIOR_PAIR_DENSITY_GRID_SIZE, +) -> tuple[np.ndarray, np.ndarray] | None: + """Estimate a 1-D Gaussian-KDE marginal density normalised to unit area. + + :param values: Posterior samples for a single parameter. + :type values: np.ndarray + :param grid_size: Number of grid points at which to evaluate the density. + :type grid_size: int + :return: ``(grid, density)`` arrays, or ``None`` if a smooth density could + not be estimated (e.g. ``scipy`` missing or degenerate samples). + :rtype: tuple[np.ndarray, np.ndarray] | None + """ + try: + from scipy.stats import gaussian_kde + except ImportError: + return None + + data = np.asarray(values, dtype=float) + data = data[np.isfinite(data)] + if data.size < _POSTERIOR_PAIR_MIN_SAMPLE_COUNT: + return None + + bounds = _posterior_axis_bounds(data) + if bounds is None: + return None + grid = np.linspace(bounds[0], bounds[1], num=grid_size) + + if np.allclose(data, data[0]): + bandwidth = max(abs(data[0]) * 0.01, 1e-6) + density = np.exp(-0.5 * ((grid - data[0]) / bandwidth) ** 2) + density /= bandwidth * np.sqrt(2.0 * np.pi) + else: + try: + density = np.asarray(gaussian_kde(data)(grid), dtype=float) + except (np.linalg.LinAlgError, ValueError): + return None + + area = np.trapezoid(density, grid) + if area <= 0: + return None + return grid, density / area + + +def _posterior_density_surface( + x_values: np.ndarray, + y_values: np.ndarray, + grid_size: int = _POSTERIOR_PAIR_CONTOUR_GRID_SIZE, +) -> tuple[np.ndarray, np.ndarray, np.ndarray] | None: + """Estimate a 2-D Gaussian-KDE density surface for one pair panel. + + :param x_values: Posterior samples for the x-axis parameter. + :type x_values: np.ndarray + :param y_values: Posterior samples for the y-axis parameter. + :type y_values: np.ndarray + :param grid_size: Number of grid points per axis. + :type grid_size: int + :return: ``(x_grid, y_grid, density)``, or ``None`` if a smooth surface + could not be estimated (e.g. ``scipy`` missing or degenerate samples). + :rtype: tuple[np.ndarray, np.ndarray, np.ndarray] | None + """ + try: + from scipy.stats import gaussian_kde + except ImportError: + return None + + x_data = np.asarray(x_values, dtype=float) + y_data = np.asarray(y_values, dtype=float) + mask = np.isfinite(x_data) & np.isfinite(y_data) + x_data = x_data[mask] + y_data = y_data[mask] + if x_data.size < _POSTERIOR_PAIR_MIN_SAMPLE_COUNT or y_data.size < _POSTERIOR_PAIR_MIN_SAMPLE_COUNT: + return None + if np.allclose(x_data, x_data[0]) and np.allclose(y_data, y_data[0]): + return None + + pair_data = np.vstack([x_data, y_data]) + covariance = np.cov(pair_data) + if np.linalg.matrix_rank(covariance) < _POSTERIOR_PAIR_COVARIANCE_RANK: + return None + + x_bounds = _posterior_axis_bounds(x_data) + y_bounds = _posterior_axis_bounds(y_data) + if x_bounds is None or y_bounds is None: + return None + x_grid = np.linspace(x_bounds[0], x_bounds[1], num=grid_size) + y_grid = np.linspace(y_bounds[0], y_bounds[1], num=grid_size) + mesh_x, mesh_y = np.meshgrid(x_grid, y_grid) + try: + kde = gaussian_kde(pair_data) + density = np.asarray(kde(np.vstack([mesh_x.ravel(), mesh_y.ravel()])), dtype=float) + except (np.linalg.LinAlgError, ValueError): + return None + density = density.reshape(mesh_x.shape) + if not np.any(np.isfinite(density)): + return None + return x_grid, y_grid, density + + +def _posterior_contour_colorscales( + x_values: np.ndarray, + y_values: np.ndarray, +) -> tuple[list, list]: + """Return sign-aware fill and line contour palettes for one pair panel. + + Negatively correlated parameter pairs use a red palette; everything else + uses blue. + + :param x_values: Posterior samples for the x-axis parameter. + :type x_values: np.ndarray + :param y_values: Posterior samples for the y-axis parameter. + :type y_values: np.ndarray + :return: ``(fill_colorscale, line_colorscale)``. + :rtype: tuple[list, list] + """ + x_data = np.asarray(x_values, dtype=float) + y_data = np.asarray(y_values, dtype=float) + mask = np.isfinite(x_data) & np.isfinite(y_data) + if np.count_nonzero(mask) >= _POSTERIOR_PAIR_MIN_SAMPLE_COUNT: + correlation = float(np.corrcoef(x_data[mask], y_data[mask])[0, 1]) + if np.isfinite(correlation) and correlation < 0: + return _POSTERIOR_NEGATIVE_CONTOUR_FILL_COLORSCALE, _POSTERIOR_NEGATIVE_CONTOUR_LINE_COLORSCALE + return _POSTERIOR_CONTOUR_FILL_COLORSCALE, _POSTERIOR_CONTOUR_LINE_COLORSCALE + + +def _add_corner_marginal( + fig: Any, + go: Any, + *, + values: np.ndarray, + row: int, + col: int, + show_legend: bool, +) -> None: + """Add a diagonal marginal-density panel (smooth KDE, histogram fallback). + + :param fig: The Plotly Figure being built. + :param go: The ``plotly.graph_objects`` module. + :param values: Posterior samples for the diagonal parameter. + :type values: np.ndarray + :param row: 1-based subplot row. + :type row: int + :param col: 1-based subplot column. + :type col: int + :param show_legend: Whether this trace should add the legend entry. + :type show_legend: bool + """ + curve = _posterior_density_curve(values) + if curve is not None: + grid, density = curve + fig.add_trace( + go.Scatter( + x=grid, + y=density, + mode='lines', + line=dict(color=_POSTERIOR_PAIR_MARGINAL_LINE_COLOR, width=1), + fill='tozeroy', + fillcolor=_POSTERIOR_PAIR_MARGINAL_FILL_COLOR, + name='Marginal density', + legendgroup='marginal', + showlegend=show_legend, + hoverinfo='skip', + ), + row=row, + col=col, + ) + return + # scipy unavailable or degenerate samples: fall back to a histogram. + fig.add_trace( + go.Histogram( + x=values, + nbinsx=40, + histnorm='probability density', + marker=dict( + color=_POSTERIOR_PAIR_MARGINAL_FILL_COLOR, + line=dict(color=_POSTERIOR_PAIR_MARGINAL_LINE_COLOR, width=1), + ), + name='Marginal density', + legendgroup='marginal', + showlegend=show_legend, + hoverinfo='skip', + ), + row=row, + col=col, + ) + + +def _corner_contour_traces( + go: Any, + x_values: np.ndarray, + y_values: np.ndarray, +) -> tuple[Any, Any] | None: + """Build filled and line 2-D KDE contour traces for one pair panel. + + :param go: The ``plotly.graph_objects`` module. + :param x_values: Posterior samples for the x-axis parameter. + :type x_values: np.ndarray + :param y_values: Posterior samples for the y-axis parameter. + :type y_values: np.ndarray + :return: ``(fill_trace, line_trace)``, or ``None`` if no smooth surface + could be estimated. + :rtype: tuple[Any, Any] | None + """ + surface = _posterior_density_surface(x_values, y_values) + if surface is None: + return None + x_grid, y_grid, density = surface + + fill_colorscale, line_colorscale = _posterior_contour_colorscales(x_values, y_values) + density_max = float(np.max(density)) + contour_start = density_max * 0.20 + contour_end = density_max * 0.95 + contour_size = density_max * 0.15 + + fill_density = np.array(density, copy=True) + fill_density[fill_density < contour_start] = np.nan + fill_trace = go.Contour( + x=x_grid, + y=y_grid, + z=fill_density, + contours=dict( + coloring='fill', + showlabels=False, + showlines=False, + start=contour_start, + end=contour_end, + size=contour_size, + ), + colorscale=fill_colorscale, + zmin=contour_start, + zmax=contour_end, + connectgaps=False, + hoverinfo='skip', + showscale=False, + zorder=1, + ) + line_trace = go.Contour( + x=x_grid, + y=y_grid, + z=density, + contours=dict( + coloring='lines', + showlabels=False, + start=contour_start, + end=contour_end, + size=contour_size, + ), + colorscale=line_colorscale, + zmin=contour_start, + zmax=contour_end, + line=dict(width=0.9), + hoverinfo='skip', + showscale=False, + zorder=2, + ) + return fill_trace, line_trace + + +def plot_corner(draws: np.ndarray, param_names: list[str]) -> Any: + """Build a parameter-correlation corner plot as a Plotly Figure. + + Smooth Gaussian-KDE marginal densities on the diagonal, a posterior + scatter overlay with filled 2-D KDE contours on the lower triangle, and a + hidden upper triangle. Contours are coloured blue for positively + correlated pairs and red for negatively correlated ones. This mirrors the + posterior pair plot in ``easydiffraction``. Requires ``plotly`` (and + ``scipy`` for the KDE smoothing; without it the diagonal falls back to a + histogram and the contours are omitted). + + :param draws: Posterior samples, shape ``(n_samples, n_params)`` or + ``(n_chains, n_draws, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :return: Plotly Figure. + """ + _require_plotly() + import plotly.graph_objects as go + from plotly.subplots import make_subplots + + draws = np.asarray(draws) + if draws.ndim == 3: + draws = draws.reshape(-1, draws.shape[-1]) + n_params = len(param_names) + + wrapped_labels = [_wrap_pair_label(name) for name in param_names] + + # Full draws drive the smooth KDE surfaces; the scatter overlay is thinned + # so large posteriors stay responsive to render and pan. + n_samples = draws.shape[0] + if n_samples > _POSTERIOR_PAIR_SCATTER_MAX_POINTS: + stride = max(1, n_samples // _POSTERIOR_PAIR_SCATTER_MAX_POINTS) + scatter_draws = draws[::stride] + else: + scatter_draws = draws + + fig = make_subplots( + rows=n_params, + cols=n_params, + horizontal_spacing=0.02, + vertical_spacing=0.02, + ) + + # Track which trace types have already been added to the legend. + legend_shown = {'marginal': False, 'scatter': False, 'contour': False} + + for row in range(n_params): + for col in range(n_params): + r, c = row + 1, col + 1 + if col > row: + fig.update_xaxes(visible=False, row=r, col=c) + fig.update_yaxes(visible=False, row=r, col=c) + continue + if col == row: + _add_corner_marginal( + fig, + go, + values=draws[:, row], + row=r, + col=c, + show_legend=not legend_shown['marginal'], + ) + legend_shown['marginal'] = True + else: + fig.add_trace( + go.Scatter( + x=scatter_draws[:, col], + y=scatter_draws[:, row], + mode='markers', + marker=dict(size=4, color=_POSTERIOR_PAIR_SCATTER_COLOR), + name='Posterior samples', + legendgroup='scatter', + showlegend=not legend_shown['scatter'], + hoverinfo='skip', + zorder=0, + ), + row=r, + col=c, + ) + legend_shown['scatter'] = True + contour_traces = _corner_contour_traces(go, draws[:, col], draws[:, row]) + if contour_traces is not None: + fill_trace, line_trace = contour_traces + fill_trace.name = 'Posterior contours' + fill_trace.legendgroup = 'contour' + fill_trace.showlegend = not legend_shown['contour'] + line_trace.legendgroup = 'contour' + line_trace.showlegend = False + fig.add_trace(fill_trace, row=r, col=c) + fig.add_trace(line_trace, row=r, col=c) + legend_shown['contour'] = True + + # Axis labels: outer edges only (bottom row x-axes, leftmost column y-axes, + # including the top-left diagonal cell so its parameter is identifiable). + for i, label in enumerate(wrapped_labels): + fig.update_xaxes(title_text=label, title_font=dict(size=10), row=n_params, col=i + 1) + fig.update_yaxes(title_text=label, title_font=dict(size=10), row=i + 1, col=1) + # Diagonal y-axes are probability density — hide their tick labels (except the + # top-left, where ticks would be the only cue about the density scale). + for i in range(1, n_params): + fig.update_yaxes(showticklabels=False, row=i + 1, col=i + 1) + + fig.update_layout( + height=max(450, 180 * n_params), + width=max(550, 180 * n_params + 140), + showlegend=True, + legend=dict( + orientation='v', + yanchor='top', + y=1.0, + xanchor='left', + x=1.02, + font=dict(size=11), + itemsizing='constant', + ), + plot_bgcolor='white', + margin=dict(l=80, r=160, t=30, b=60), + ) + fig.update_xaxes(showgrid=False, zeroline=False, ticks='outside') + fig.update_yaxes(showgrid=False, zeroline=False, ticks='outside') + return fig + + +def plot_trace(draws: np.ndarray, param_names: list[str], return_figure: bool = False, **kwargs) -> Any: + """Plot MCMC trace plot. + + When *return_figure* is ``True`` a Plotly ``Figure`` is returned instead of + being displayed inline; the caller is responsible for rendering it. This + requires the ``plotly`` package. + + :param draws: Posterior samples, shape ``(n_chains, n_draws, n_params)`` or + ``(n_draws, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :param return_figure: Return a Plotly Figure instead of rendering inline. + :type return_figure: bool + :param kwargs: Additional keyword arguments passed to ``arviz.plot_trace`` + when *return_figure* is ``False``. + :return: Plotly Figure when *return_figure* is ``True``, otherwise ``None``. + """ + draws = np.asarray(draws) + if draws.ndim == 2: + draws = draws[np.newaxis, ...] # (1, n_draws, n_params) + # draws shape: (n_chains, n_draws, n_params) + + if return_figure: + try: + import plotly.graph_objects as go + from plotly.subplots import make_subplots + except ImportError: + warnings.warn( + 'The ``plotly`` library is required to build the trace figure. Install it with ``pip install plotly``.', + UserWarning, + stacklevel=2, + ) + return None + + n_params = len(param_names) + n_chains = draws.shape[0] + fig = make_subplots( + rows=n_params, + cols=2, + column_widths=[0.6, 0.4], + ) + colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'] + for i, name in enumerate(param_names): + row = i + 1 + show_legend = i == 0 + for c in range(n_chains): + chain_draws = draws[c, :, i] + color = colors[c % len(colors)] + fig.add_trace( + go.Scatter( + y=chain_draws, + mode='lines', + line=dict(color=color, width=1), + name=f'chain {c}', + legendgroup=f'chain {c}', + showlegend=show_legend, + ), + row=row, + col=1, + ) + fig.add_trace( + go.Histogram( + x=chain_draws, + marker_color=color, + opacity=0.6, + name=f'chain {c}', + legendgroup=f'chain {c}', + showlegend=show_legend, + nbinsx=40, + ), + row=row, + col=2, + ) + fig.update_yaxes(title_text=name, title_font=dict(size=10), row=row, col=1) + fig.update_xaxes(title_text=name, title_font=dict(size=10), row=row, col=2) + fig.update_yaxes(title_text='Count', title_font=dict(size=10), row=row, col=2) + fig.update_xaxes(title_text='Draw index', title_font=dict(size=10), row=n_params, col=1) + fig.update_layout( + height=max(300, 200 * n_params), + barmode='overlay', + legend=dict(orientation='h', yanchor='bottom', y=1.02, xanchor='right', x=1, font=dict(size=10)), + ) + return fig + + _require_arviz() + idata = _to_arviz_data(draws, param_names) + _arviz.plot_trace(idata, var_names=param_names, **kwargs) + return None + + +def _posterior_marginal_y_range( + values: np.ndarray, + density_curve: tuple[np.ndarray, np.ndarray] | None, +) -> tuple[float, float] | None: + """Return a ``(0, max)`` y-axis range covering histogram and KDE density. + + The range spans the larger of the histogram (probability-density normalised) + and smooth-KDE peaks so credible-interval bands and reference lines, which + are drawn as full-height traces, reach the top of the panel. + + :param values: Posterior samples for a single parameter. + :type values: np.ndarray + :param density_curve: ``(grid, density)`` from :func:`_posterior_density_curve`, or ``None``. + :type density_curve: tuple[np.ndarray, np.ndarray] | None + :return: ``(0.0, padded_max)`` range, or ``None`` if no density is available. + :rtype: tuple[float, float] | None + """ + data = np.asarray(values, dtype=float) + data = data[np.isfinite(data)] + maxima: list[float] = [] + if data.size: + hist, _ = np.histogram(data, bins=40, density=True) + if hist.size: + maxima.append(float(np.max(hist))) + if density_curve is not None: + maxima.append(float(np.max(density_curve[1]))) + if not maxima: + return None + y_max = max(maxima) + if y_max <= 0: + return None + return 0.0, y_max * 1.08 + + +def _posterior_interval_band_trace( + go: Any, + *, + x0: float, + x1: float, + y_range: tuple[float, float], + name: str, + color: str, + show_legend: bool, +) -> Any: + """Return a filled rectangle marking a credible interval. + + :param go: The ``plotly.graph_objects`` module. + :param x0: Lower interval bound. + :type x0: float + :param x1: Upper interval bound. + :type x1: float + :param y_range: Panel y-axis range the band should span. + :type y_range: tuple[float, float] + :param name: Legend/trace name. + :type name: str + :param color: Fill colour. + :type color: str + :param show_legend: Whether this trace adds the legend entry. + :type show_legend: bool + :return: A Plotly Scatter trace. + """ + return go.Scatter( + x=[x0, x1, x1, x0, x0], + y=[y_range[0], y_range[0], y_range[1], y_range[1], y_range[0]], + mode='lines', + fill='toself', + fillcolor=color, + line=dict(color=color, width=0), + name=name, + legendgroup=name, + showlegend=show_legend, + hoverinfo='skip', + ) + + +def _posterior_reference_line_trace( + go: Any, + *, + x_value: float, + y_range: tuple[float, float], + name: str, + color: str, + dash: str, + show_legend: bool, +) -> Any: + """Return a vertical reference line for a posterior marginal panel. + + :param go: The ``plotly.graph_objects`` module. + :param x_value: Parameter value at which to draw the line. + :type x_value: float + :param y_range: Panel y-axis range the line should span. + :type y_range: tuple[float, float] + :param name: Legend/trace name. + :type name: str + :param color: Line colour. + :type color: str + :param dash: Plotly dash style (e.g. ``'dash'``, ``'dot'``). + :type dash: str + :param show_legend: Whether this trace adds the legend entry. + :type show_legend: bool + :return: A Plotly Scatter trace. + """ + return go.Scatter( + x=[x_value, x_value], + y=[y_range[0], y_range[1]], + mode='lines', + line=dict(color=color, width=2, dash=dash), + name=name, + legendgroup=name, + showlegend=show_legend, + hovertemplate=f'{name}: %{{x:.4f}}', + ) + + +def plot_distribution( + draws: np.ndarray, + param_names: list[str], + logp: np.ndarray | None = None, + return_figure: bool = False, + **kwargs, +) -> Any: + """Plot marginal posterior distributions for each parameter. + + Each panel overlays, mirroring ``easydiffraction``'s + ``project.display.posterior.distribution()``: + + * the posterior **histogram** (probability-density normalised), + * a smooth **Gaussian-KDE marginal** density curve (requires ``scipy``; + omitted if unavailable or the samples are degenerate), + * a shaded **95% credible interval** (equal-tailed 2.5/97.5 percentiles), + * a dashed **median** line, and + * a dotted **best posterior sample** line when *logp* is supplied. + + When *return_figure* is ``True`` a Plotly ``Figure`` is returned. + + :param draws: Posterior samples, shape ``(n_samples, n_params)`` or + ``(n_chains, n_draws, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :param logp: Log-posterior values, shape ``(n_samples,)``. When given, the + draw with the largest value marks the best posterior sample. + :type logp: np.ndarray | None + :param return_figure: Return a Plotly Figure instead of rendering inline. + :type return_figure: bool + :param kwargs: Additional keyword arguments (currently unused). + :return: Plotly Figure when *return_figure* is ``True``, otherwise ``None``. + """ + draws = np.asarray(draws) + if draws.ndim == 3: + draws = draws.reshape(-1, draws.shape[-1]) + # draws shape: (n_samples, n_params) + + best_index: int | None = None + if logp is not None: + logp = np.asarray(logp).reshape(-1) + if logp.size == draws.shape[0] and np.any(np.isfinite(logp)): + best_index = int(np.nanargmax(logp)) + + if not return_figure: + return None + + try: + import plotly.graph_objects as go + from plotly.subplots import make_subplots + except ImportError: + warnings.warn( + 'The ``plotly`` library is required to build the distribution figure. Install it with ``pip install plotly``.', + UserWarning, + stacklevel=2, + ) + return None + + n_params = len(param_names) + n_cols = min(3, n_params) + n_rows = (n_params + n_cols - 1) // n_cols + fig = make_subplots(rows=n_rows, cols=n_cols) + + # Each trace type contributes a single shared legend entry. + legend_shown = { + 'histogram': False, + 'marginal': False, + 'interval': False, + 'median': False, + 'best': False, + } + + for i, name in enumerate(param_names): + row = i // n_cols + 1 + col = i % n_cols + 1 + values = draws[:, i] + + density_curve = _posterior_density_curve(values) + y_range = _posterior_marginal_y_range(values, density_curve) + lower, upper = (float(v) for v in np.percentile(values, [2.5, 97.5])) + + # Credible-interval band first so it sits behind the density traces. + if y_range is not None: + fig.add_trace( + _posterior_interval_band_trace( + go, + x0=lower, + x1=upper, + y_range=y_range, + name='95% credible interval', + color=_POSTERIOR_INTERVAL_95_FILL_COLOR, + show_legend=not legend_shown['interval'], + ), + row=row, + col=col, + ) + legend_shown['interval'] = True + + fig.add_trace( + go.Histogram( + x=values, + histnorm='probability density', + marker=dict( + color=_POSTERIOR_HISTOGRAM_FILL_COLOR, + line=dict(color=_POSTERIOR_HISTOGRAM_LINE_COLOR, width=1), + ), + opacity=0.82, + nbinsx=40, + name='Posterior histogram', + legendgroup='histogram', + showlegend=not legend_shown['histogram'], + hovertemplate='sample=%{x:.4f}
density: %{y:.2f}', + ), + row=row, + col=col, + ) + legend_shown['histogram'] = True + + if density_curve is not None: + grid, density = density_curve + fig.add_trace( + go.Scatter( + x=grid, + y=density, + mode='lines', + line=dict(color=_POSTERIOR_PAIR_MARGINAL_LINE_COLOR, width=2), + fill='tozeroy', + fillcolor=_POSTERIOR_PAIR_MARGINAL_FILL_COLOR, + name='Marginal density', + legendgroup='marginal', + showlegend=not legend_shown['marginal'], + hovertemplate=f'{name}: %{{x:.4f}}
density: %{{y:.4f}}', + ), + row=row, + col=col, + ) + legend_shown['marginal'] = True + + if y_range is not None: + fig.add_trace( + _posterior_reference_line_trace( + go, + x_value=float(np.median(values)), + y_range=y_range, + name='Median', + color=_POSTERIOR_MEDIAN_LINE_COLOR, + dash='dash', + show_legend=not legend_shown['median'], + ), + row=row, + col=col, + ) + legend_shown['median'] = True + if best_index is not None: + fig.add_trace( + _posterior_reference_line_trace( + go, + x_value=float(values[best_index]), + y_range=y_range, + name='Best posterior sample', + color=_POSTERIOR_POINT_ESTIMATE_LINE_COLOR, + dash='dot', + show_legend=not legend_shown['best'], + ), + row=row, + col=col, + ) + legend_shown['best'] = True + fig.update_yaxes(range=list(y_range), row=row, col=col) + + if density_curve is not None: + fig.update_xaxes( + range=[float(density_curve[0][0]), float(density_curve[0][-1])], + row=row, + col=col, + ) + fig.update_xaxes(title_text=name, title_font=dict(size=11), row=row, col=col) + fig.update_yaxes(title_text='Probability density', title_font=dict(size=11), row=row, col=col) + + fig.update_layout( + height=max(300, 250 * n_rows), + barmode='overlay', + showlegend=True, + legend=dict(font=dict(size=10)), + plot_bgcolor='white', + ) + fig.update_xaxes(showgrid=False, zeroline=False, ticks='outside') + fig.update_yaxes(showgrid=False, zeroline=False, ticks='outside') + return fig + + +def credible_intervals( + draws: np.ndarray, + param_names: list[str], + alpha: float = 0.95, +) -> dict: + """Compute equal-tailed credible intervals for each parameter. + + :param draws: Posterior samples, shape ``(n_samples, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names (one per column). + :type param_names: list[str] + :param alpha: Credible interval width (e.g. 0.95 for 95%). + :type alpha: float + :return: Dictionary mapping parameter name to ``(lower, upper)``. + :rtype: dict + """ + draws = np.asarray(draws) + tail = (1.0 - alpha) / 2.0 + lo_pct = tail * 100 + hi_pct = (1.0 - tail) * 100 + result = {} + for i, name in enumerate(param_names): + col = draws[:, i] + lo, hi = np.percentile(col, [lo_pct, hi_pct]) + result[name] = (float(lo), float(hi)) + return result + + +def _save_parameter_state(model) -> dict: + """Save the current values and errors of all free parameters in a model. + + :param model: A reflectometry model with ``get_parameters()``. + :return: Dictionary mapping ``unique_name`` to ``(value, error)``. + :rtype: dict + """ + state = {} + for param in model.get_parameters(): + state[param.unique_name] = (param.value, param.error) + return state + + +def _restore_parameter_state(model, state: dict) -> None: + """Restore parameter values and errors from a saved state. + + :param model: A reflectometry model with ``get_parameters()``. + :param state: Dictionary mapping ``unique_name`` to ``(value, error)``. + """ + for param in model.get_parameters(): + if param.unique_name in state: + param.value = state[param.unique_name][0] + param.error = state[param.unique_name][1] + + +def _apply_draw(model, draws: np.ndarray, param_names: list[str], row: int) -> None: + """Apply a single posterior draw to the model parameters. + + Parameter lookup uses ``unique_name``, matching the BUMPS names after + removing the minimizer prefix, which avoids collisions when repeated models + or multi-contrast fits contain similarly named parameters. + + :param model: A reflectometry model with ``get_parameters()``. + :param draws: Posterior samples array. + :param param_names: Parameter names matching the columns of ``draws``. + :param row: Index of the draw to apply. + """ + param_lookup = {p.unique_name: p for p in model.get_parameters()} + for j, name in enumerate(param_names): + if name in param_lookup: + param_lookup[name].value = float(draws[row, j]) + + +def posterior_predictive_reflectivity( + draws: np.ndarray, + param_names: list[str], + model, + q_values: np.ndarray, + n_samples: int = 200, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """Compute the posterior predictive reflectivity with credible intervals. + + Parameter values and errors are saved before applying any posterior draw + and restored in a ``finally`` block, so the model is not left mutated. + + :param draws: Posterior samples, shape ``(n_samples_posterior, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names matching the columns of ``draws``. + :type param_names: list[str] + :param model: A reflectometry model with ``interface.fit_func``. + :param q_values: Q values at which to evaluate reflectivity. + :type q_values: np.ndarray + :param n_samples: Number of posterior draws to use (last ``n_samples``). + :type n_samples: int + :return: Tuple of ``(median, lower_95, upper_95)`` reflectivity arrays. + :rtype: tuple[np.ndarray, np.ndarray, np.ndarray] + """ + draws = np.asarray(draws) + q_values = np.asarray(q_values) + + n_total = draws.shape[0] + n_use = min(n_samples, n_total) + sample_indices = range(n_total - n_use, n_total) + + saved_state = _save_parameter_state(model) + try: + reflectivity_samples = [] + for i in sample_indices: + _apply_draw(model, draws, param_names, i) + r_calc = model.interface.fit_func(q_values, model.unique_name) + reflectivity_samples.append(np.asarray(r_calc)) + finally: + _restore_parameter_state(model, saved_state) + + reflectivity_samples = np.array(reflectivity_samples) + median = np.median(reflectivity_samples, axis=0) + lower = np.percentile(reflectivity_samples, 2.5, axis=0) + upper = np.percentile(reflectivity_samples, 97.5, axis=0) + return median, lower, upper + + +def posterior_predictive_sld_profile( + draws: np.ndarray, + param_names: list[str], + model, + n_samples: int = 200, +) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + """Compute the posterior predictive SLD profile with credible intervals. + + Parameter values and errors are saved before applying any posterior draw + and restored in a ``finally`` block, so the model is not left mutated. + + :param draws: Posterior samples, shape ``(n_samples_posterior, n_params)``. + :type draws: np.ndarray + :param param_names: Parameter names matching the columns of ``draws``. + :type param_names: list[str] + :param model: A reflectometry model with ``interface.sld_profile``. + :param n_samples: Number of posterior draws to use (last ``n_samples``). + :type n_samples: int + :return: Tuple of ``(z, median, lower_95, upper_95)`` SLD profile arrays. + :rtype: tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray] + """ + draws = np.asarray(draws) + + n_total = draws.shape[0] + n_use = min(n_samples, n_total) + sample_indices = range(n_total - n_use, n_total) + + saved_state = _save_parameter_state(model) + try: + sld_samples = [] + z_shared = None + for i in sample_indices: + _apply_draw(model, draws, param_names, i) + z, sld = model.interface.sld_profile(model.unique_name) + if z_shared is None: + z_shared = np.asarray(z) + sld_samples.append(np.asarray(sld)) + finally: + _restore_parameter_state(model, saved_state) + + sld_samples = np.array(sld_samples) + median = np.median(sld_samples, axis=0) + lower = np.percentile(sld_samples, 2.5, axis=0) + upper = np.percentile(sld_samples, 97.5, axis=0) + return z_shared, median, lower, upper + + +# =================================================================== +# Persistence helpers — save / load a posterior trace to / from disk +# =================================================================== + +_SIDECAR_SCHEMA_VERSION = 1 + + +def _easyreflectometry_version() -> str: + """Return the installed easyreflectometry version string.""" + try: + from importlib.metadata import version as _v + + return _v('easyreflectometry') + except Exception: + return 'unknown' + + +def _data_fingerprint( + x_list: list[np.ndarray], + y_list: list[np.ndarray], + w_list: list[np.ndarray], +) -> str | None: + """Return a SHA-256 hex digest of concatenated (x|y|weights), or None.""" + try: + h = hashlib.sha256() + for arr in list(x_list) + list(y_list) + list(w_list): + h.update(np.ascontiguousarray(arr, dtype=np.float64).tobytes()) + return h.hexdigest() + except Exception: + return None + + +def save_posterior(results: 'PosteriorResults', path: str) -> None: + """Persist a sampling trace to disk using BUMPS' native state files. + + Writes ``-*.mc`` (BUMPS ``save_state`` output) plus a sidecar + ``.params.json`` holding parameter names and metadata so that + :func:`load_posterior` can reconstruct a fully populated + :class:`PosteriorResults` without re-deriving names from the model. + + Note that ``save_state`` writes **multiple** files (one per DREAM + component: chain, point, and stats). The ``path`` argument is a + prefix; the actual files will be ``-chain.mc``, + ``-point.mc``, and ``-stats.mc``. + + :param results: The posterior results to persist. Must have a + non-``None`` ``sampler_state``. + :type results: PosteriorResults + :param path: File path prefix. BUMPS appends its own suffixes. + :type path: str + :raises ValueError: If ``results.sampler_state`` is ``None``. + :raises TypeError: If ``results.sampler_state`` is not a BUMPS + ``MCMCDraw`` object. + """ + from bumps.dream.state import MCMCDraw + from bumps.dream.state import save_state + + if results.sampler_state is None: + raise ValueError( + 'This PosteriorResults has no sampler_state, so the chain ' + 'cannot be saved or resumed. Re-run sample() and wrap the ' + "returned dict's 'state' value into PosteriorResults." + ) + if not isinstance(results.sampler_state, MCMCDraw): + raise TypeError( + f'sampler_state must be a BUMPS MCMCDraw object, got ' + f'{type(results.sampler_state).__name__}. Only BUMPS DREAM ' + 'traces can be persisted with save_posterior.' + ) + + save_state(results.sampler_state, path) + + # Write the sidecar JSON + sidecar = { + 'schema_version': _SIDECAR_SCHEMA_VERSION, + 'param_names': results.param_names, + 'easyreflectometry_version': _easyreflectometry_version(), + } + with open(f'{path}.params.json', 'w') as f: + json.dump(sidecar, f, indent=2) + + +def load_posterior(path: str, skip: int = 0) -> 'PosteriorResults': + """Reload a trace saved by :func:`save_posterior` into a + :class:`PosteriorResults`. + + The returned object's ``sampler_state`` can be fed back into + ``MultiFitter.mcmc_sample(..., resume_state=...)`` to extend the chain. + + :param path: File path prefix used in :func:`save_posterior`. + :type path: str + :param skip: Discard the first ``skip`` saved generations on load, + forwarded to ``bumps.dream.state.load_state(path, skip=skip)``. + Useful for trimming additional burn-in without re-sampling. + :type skip: int + :return: A fully populated :class:`PosteriorResults`. + :rtype: PosteriorResults + """ + from bumps.dream.state import load_state + + state = load_state(path, skip=skip) + _draw = state.draw() + draws = _draw.points + logp = _draw.logp # .logp is on the Draw object, NOT state.logp + + # Restore param_names: prefer the sidecar; fall back to state.labels + param_names: list[str] | None = None + try: + with open(f'{path}.params.json', 'r') as f: + sidecar = json.load(f) + if sidecar.get('schema_version') == _SIDECAR_SCHEMA_VERSION: + param_names = sidecar.get('param_names') + except (FileNotFoundError, json.JSONDecodeError, KeyError): + pass + + if param_names is None: + # Fallback: strip BUMPS 'p' prefix from state.labels + param_names = [ + lbl[len(MINIMIZER_PARAMETER_PREFIX) :] if lbl.startswith(MINIMIZER_PARAMETER_PREFIX) else lbl + for lbl in state.labels + ] + + return PosteriorResults( + draws=draws, + param_names=param_names, + logp=logp, + sampler_state=state, + ) diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 78f74e68..83a3f6eb 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -3,6 +3,8 @@ import warnings +from typing import Any +from typing import Callable import numpy as np import scipp as sc @@ -353,6 +355,87 @@ def fit_single_data_set_1d(self, data: DataSet1D, objective: str | None = None) ] return result + def mcmc_sample( + self, + data: sc.DataGroup, + samples: int = 10000, + burn: int = 2000, + thin: int = 10, + population: int | None = None, + objective: str | None = None, + initializer: str | None = None, + progress_callback: Callable[..., Any] | None = None, + abort_test: Callable[[], bool] | None = None, + ) -> dict: + """Run Bayesian MCMC sampling on reflectometry data using the DREAM sampler. + + Requires that the minimizer is a BUMPS instance (i.e. the minimizer was + switched to ``AvailableMinimizers.Bumps``). + + :param data: DataGroup with reflectivity data. + :param samples: Number of retained DREAM samples requested from BUMPS. + :param burn: Burn-in steps. + :param thin: Thinning interval. + :param population: BUMPS DREAM population count for advanced users. + :param objective: Zero-variance handling strategy. + :param initializer: DREAM population initializer. One of ``'eps'``, + ``'cov'``, ``'lhs'``, or ``'random'``. By default, None (BUMPS + uses ``'eps'``). + — the population already exists in the saved state. + :param progress_callback: Optional callback for progress updates during + sampling. Forwarded to the core MultiFitter. + :return: Dictionary with keys ``'draws'``, ``'param_names'``, ``'state'``, + and ``'logp'``. + :raises RuntimeError: If the current minimizer is not a BUMPS instance. + """ + minimizer = self.easy_science_multi_fitter.minimizer + if not (hasattr(minimizer, 'package') and minimizer.package == 'bumps'): + raise RuntimeError( + 'Bayesian sampling requires a BUMPS minimizer. ' + 'Use ``fitter.switch_minimizer(AvailableMinimizers.Bumps)`` first.' + ) + + obj = _validate_objective(objective) if objective is not None else self._objective + + refl_nums = [k[3:] for k in data['coords'].keys() if k.startswith('Qz_')] + x = [] + y = [] + dy = [] + + # Process each reflectivity dataset + for i in refl_nums: + x_vals = data['coords'][f'Qz_{i}'].values + y_vals = data['data'][f'R_{i}'].values + variances = data['data'][f'R_{i}'].variances + + x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj) + + if stats['masked'] > 0: + warnings.warn( + f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during sampling.', + UserWarning, + ) + x.append(x_out) + y.append(y_eff) + dy.append(weights) + + # Delegate the actual BUMPS/DREAM sampling to the core MultiFitter + sampler_kwargs = {} + if initializer is not None: + sampler_kwargs['init'] = initializer + return self.easy_science_multi_fitter.mcmc_sample( + x=x, + y=y, + weights=dy, + samples=samples, + burn=burn, + thin=thin, + population=population, + sampler_kwargs=sampler_kwargs or None, + progress_callback=progress_callback, + abort_test=abort_test, + ) + @property def chi2(self) -> float | None: """Total chi-squared across all fitted datasets, or None if no fit has been performed.""" diff --git a/tests/_static/amor_reduced_iofq.ort b/tests/_static/amor_reduced_iofq.ort new file mode 100644 index 00000000..534097d2 --- /dev/null +++ b/tests/_static/amor_reduced_iofq.ort @@ -0,0 +1,236 @@ +# # ORSO reflectivity data file | 1.1 standard | YAML encoding | https://www.reflectometry.org/ +# data_source: +# owner: +# name: A. Luchini +# affiliation: null +# contact: '' +# experiment: +# title: ESS solid-liquid cell test +# instrument: Amor +# start_date: 2024-09-12T03:32:57 +# probe: neutron +# facility: SINQ +# sample: +# name: ESS004 Si|dmpc+ZipAdiscs|D2O +# model: +# stack: Si | SiO2 | pc_head | d54dm_tail | d54dm_tail | pc_head | D2O +# measurement: +# instrument_settings: +# incident_angle: {min: 0.006719518471565493, max: 0.013002693060859875, unit: rad} +# wavelength: {min: 3.0031411323142234, max: 12.499958254247156, unit: angstrom} +# polarization: null +# data_files: +# - file: amor2024n004079.hdf +# - file: amor2024n004080.hdf +# - file: amor2024n004081.hdf +# additional_files: +# - file: amor2024n004152.hdf +# comment: supermirror +# reduction: +# software: {name: ess.reflectometry, version: 0.1.dev1+g180c20f, platform: Linux} +# timestamp: 2025-06-16T03:13:22.094956+00:00 +# creator: +# name: Max Mustermann +# affiliation: European Spallation Source ERIC +# contact: max.mustermann@ess.eu +# corrections: +# - chopper ToF correction +# - footprint correction +# - supermirror calibration +# data_set: 0 +# columns: +# - {name: Qz, unit: 1/angstrom, physical_quantity: wavevector transfer} +# - {name: R, physical_quantity: reflectivity} +# - {name: sR, physical_quantity: standard deviation of reflectivity} +# - {name: sQz, unit: 1/angstrom, physical_quantity: standard deviation of wavevector +# transfer resolution} +# # Qz (1/angstrom) R sR sQz (1/angstrom) +1.0044995237394449e-02 9.8603449665594300e-01 7.8179479714162482e-03 4.1363725159788978e-04 +1.0135390626460987e-02 9.8245104333478350e-01 7.5570347164487421e-03 4.1670106126586831e-04 +1.0226599487925606e-02 9.7696417593495455e-01 7.3448109829999759e-03 4.1828901426624527e-04 +1.0318629142265039e-02 9.8564334802005227e-01 7.3906865714743432e-03 4.1962414384512657e-04 +1.0411486975833342e-02 9.5169127761079275e-01 6.9599717030842763e-03 4.2310566259624898e-04 +1.0505180441454711e-02 9.7407382190188407e-01 6.8907576938003132e-03 4.2645004390068738e-04 +1.0599717059021668e-02 9.8426912609602146e-01 6.7562375631018429e-03 4.2928423579183424e-04 +1.0695104416098604e-02 9.7450248676141815e-01 6.5034923168526652e-03 4.3253452179161566e-04 +1.0791350168530762e-02 9.8118888188357278e-01 6.3716833404347311e-03 4.3480071560078745e-04 +1.0888462041058696e-02 9.8887990521784652e-01 6.2638375299793724e-03 4.3927220128707435e-04 +1.0986447827938273e-02 1.0106569599007325e+00 6.2384780198697382e-03 4.4223603304064865e-04 +1.1085315393566239e-02 1.0015005572426214e+00 6.0240780687788762e-03 4.4527232322051240e-04 +1.1185072673111411e-02 1.0177740726436633e+00 5.9882664258192365e-03 4.4820858865534128e-04 +1.1285727673151575e-02 9.8921638764095243e-01 5.6963317802609156e-03 4.5265854416738833e-04 +1.1387288472316090e-02 1.0201869446242222e+00 5.7196396022441455e-03 4.5581306060731361e-04 +1.1489763221934280e-02 1.0008249942362757e+00 5.4809677965727164e-03 4.5871481927092051e-04 +1.1593160146689669e-02 1.0025584609428606e+00 5.4013279001621436e-03 4.6292087220993082e-04 +1.1697487545280105e-02 1.0263729247237372e+00 5.3895056224825362e-03 4.6600726482663279e-04 +1.1802753791083805e-02 1.0193693802271575e+00 5.2267157416687896e-03 4.6970776586345347e-04 +1.1908967332831416e-02 1.0103354333924730e+00 5.0871137990220350e-03 4.7319692527195552e-04 +1.2016136695284119e-02 1.0094491046259855e+00 4.9950652800967200e-03 4.7648929966986469e-04 +1.2124270479917813e-02 1.0409814363689365e+00 5.0293613302694624e-03 4.7972371645923123e-04 +1.2233377365613496e-02 1.0223059605490794e+00 4.8607306388079325e-03 4.8407536387068818e-04 +1.2343466109353831e-02 1.0252532931453100e+00 4.7993351510761256e-03 4.8695863655647632e-04 +1.2454545546925976e-02 1.0128499829761819e+00 4.6788897952293471e-03 4.9180902124788242e-04 +1.2566624593630759e-02 9.9854962639967948e-01 4.5570537317499698e-03 4.9464614477104059e-04 +1.2679712244998228e-02 1.0054021277720633e+00 4.4881193266977145e-03 4.9880191982438712e-04 +1.2793817577509629e-02 1.0093717851660171e+00 4.4560096498985390e-03 5.0251488214466983e-04 +1.2908949749325898e-02 1.0010082832213376e+00 4.3674046766402144e-03 5.0611872242520696e-04 +1.3025118001022684e-02 9.9997502865166965e-01 4.3246987974745249e-03 5.1087145503655442e-04 +1.3142331656332034e-02 1.0100273480052027e+00 4.2936439281344493e-03 5.1496622270002569e-04 +1.3260600122890685e-02 9.9862071869848812e-01 4.2029742286579241e-03 5.1907625237436288e-04 +1.3379932892995151e-02 1.0164823930731817e+00 4.2357430748032766e-03 5.2294295070626966e-04 +1.3500339544363577e-02 9.7996155603147039e-01 4.0449708337456014e-03 5.2793717559712617e-04 +1.3621829740904442e-02 9.9247214969196795e-01 4.0645114477996080e-03 5.3257311502360278e-04 +1.3744413233492195e-02 1.0037016435356869e+00 4.0682004028257997e-03 5.3633920455711120e-04 +1.3868099860749876e-02 9.8685070242340178e-01 3.9754464443643002e-03 5.4020499389089403e-04 +1.3992899549838754e-02 9.7696514386858824e-01 3.9134752355823154e-03 5.4470166910886920e-04 +1.4118822317255090e-02 9.7178241076301930e-01 3.8866934076358353e-03 5.4976238836404348e-04 +1.4245878269634081e-02 9.2250010832578311e-01 3.7445142123583479e-03 5.5305864996756332e-04 +1.4374077604561006e-02 8.2214390672146609e-01 3.4677481882741967e-03 5.5843124972314361e-04 +1.4503430611389697e-02 7.1353253457907029e-01 3.2166390980214502e-03 5.6155042910128778e-04 +1.4633947672068381e-02 6.0030958518931332e-01 2.9309926173895426e-03 5.6437947346971672e-04 +1.4765639261972916e-02 4.9166627882772374e-01 2.6392357491950885e-03 5.6950953682093216e-04 +1.4898515950747572e-02 3.9563596998583606e-01 2.3544433153957511e-03 5.7345285137804425e-04 +1.5032588403153347e-02 3.3008462019887669e-01 2.1288969526833288e-03 5.7872465889241900e-04 +1.5167867379923934e-02 2.8348628624360400e-01 1.9645569907311548e-03 5.8367885330035823e-04 +1.5304363738629378e-02 2.4971863206251596e-01 1.8334842472432855e-03 5.8770342136830621e-04 +1.5442088434547505e-02 2.2246216998804652e-01 1.7261069959473119e-03 5.9304201275462809e-04 +1.5581052521543216e-02 1.9665563555021481e-01 1.6004802471234396e-03 5.9843253042245518e-04 +1.5721267152955666e-02 1.7930778808508194e-01 1.5280211872099028e-03 6.0297178899375997e-04 +1.5862743582493424e-02 1.6235463616506585e-01 1.4414618539511184e-03 6.0854894037747011e-04 +1.6005493165137739e-02 1.4508570827061523e-01 1.3449372866973191e-03 6.1344256859332798e-04 +1.6149527358053868e-02 1.3326095171286856e-01 1.2771658081253238e-03 6.1789422621403027e-04 +1.6294857721510625e-02 1.2721780987752765e-01 1.2567160206851790e-03 6.2282221685751999e-04 +1.6441495919808258e-02 1.1360640589351807e-01 1.1729308180692003e-03 6.2841066232835951e-04 +1.6589453722214591e-02 1.0356366919550507e-01 1.1152902778779911e-03 6.3321849045516547e-04 +1.6738743003909644e-02 9.6586762699090237e-02 1.0726325643774977e-03 6.3892800485394416e-04 +1.6889375746938759e-02 8.9077992838027684e-02 1.0185548898229684e-03 6.4389516784577148e-04 +1.7041364041174276e-02 8.2719027886160049e-02 9.8358774221977280e-04 6.4844692107349829e-04 +1.7194720085285855e-02 7.6563380615004603e-02 9.4034688430919878e-04 6.5481558273970013e-04 +1.7349456187719568e-02 7.2490220764900221e-02 9.1415942677435956e-04 6.5926814059131156e-04 +1.7505584767685781e-02 6.4251252027250003e-02 8.4532581653434444e-04 6.6511620008951754e-04 +1.7663118356155916e-02 6.1368551284949335e-02 8.3045196505704150e-04 6.7038946412950238e-04 +1.7822069596868211e-02 5.5794193605098193e-02 7.9049687607934710e-04 6.7542025368706586e-04 +1.7982451247342511e-02 5.3244900196045324e-02 7.6950986679186933e-04 6.8159065116678449e-04 +1.8144276179904172e-02 4.9895039079214679e-02 7.4183354352460121e-04 6.8673563730519630e-04 +1.8307557382717225e-02 4.6369745695198222e-02 7.0676877881829467e-04 6.9215160152456118e-04 +1.8472307960826800e-02 4.2676736819516385e-02 6.7850307559999860e-04 6.9707095735638193e-04 +1.8638541137210956e-02 4.0374548477077950e-02 6.6411546231271486e-04 7.0383181466090615e-04 +1.8806270253841958e-02 3.6999978648876108e-02 6.3332951956318324e-04 7.0895990372178978e-04 +1.8975508772757121e-02 3.4568332978177671e-02 6.0650056249067518e-04 7.1427816321714709e-04 +1.9146270277139256e-02 3.4072934265176318e-02 6.0590467866145038e-04 7.1957920659550430e-04 +1.9318568472406893e-02 3.0046042729325925e-02 5.6472505072440728e-04 7.2611474421825758e-04 +1.9492417187314270e-02 2.8365919147004797e-02 5.4500253028234424e-04 7.3184171000717979e-04 +1.9667830375061243e-02 2.6058834561471629e-02 5.2179425869031267e-04 7.3775340044820266e-04 +1.9844822114413171e-02 2.4746345854375979e-02 5.1107964466043712e-04 7.4155194956120908e-04 +2.0023406610830900e-02 2.3851195066905306e-02 4.9916964513846960e-04 7.4830622458566356e-04 +2.0203598197610889e-02 2.1253241483291857e-02 4.6980003523848648e-04 7.5524727677442024e-04 +2.0385411337035607e-02 2.0999497560799319e-02 4.6455494741044496e-04 7.6137631518134383e-04 +2.0568860621534294e-02 1.9438222062193970e-02 4.5148435621545892e-04 7.6715006979192818e-04 +2.0753960774854155e-02 1.7911668785073356e-02 4.3347108302645740e-04 7.7250543628190973e-04 +2.0940726653242085e-02 1.7063681872190845e-02 4.2249940053998666e-04 7.7959601825903526e-04 +2.1129173246637063e-02 1.5751821495561726e-02 4.0609429536334887e-04 7.8544440633751956e-04 +2.1319315679873243e-02 1.5256503430763645e-02 4.0096295989391071e-04 7.9077472093173310e-04 +2.1511169213893868e-02 1.5247551172600692e-02 3.9817006524973524e-04 7.9725169368577713e-04 +2.1704749246976133e-02 1.4738797155940621e-02 3.9569829441703268e-04 8.0363974559300474e-04 +2.1900071315967076e-02 1.2265720162206365e-02 3.6170484268039949e-04 8.1043237181891976e-04 +2.2097151097530542e-02 1.1435145048888439e-02 3.4884949178788980e-04 8.1613315421321807e-04 +2.2296004409405420e-02 1.1758574408129640e-02 3.5407895511419332e-04 8.2250218837096848e-04 +2.2496647211675196e-02 1.1148262991366597e-02 3.4624925624656392e-04 8.2946886150455192e-04 +2.2699095608048902e-02 1.1134293056936589e-02 3.4897470337361412e-04 8.3654975749666795e-04 +2.2903365847153599e-02 8.9691322016261406e-03 3.0681202709152125e-04 8.4252256109452312e-04 +2.3109474323838523e-02 9.4329068912666313e-03 3.1750543304164013e-04 8.4935410242671769e-04 +2.3317437580490936e-02 8.2774928771431680e-03 2.9965588979169108e-04 8.5682822910394178e-04 +2.3527272308363826e-02 7.8557806942254529e-03 2.9447717006224908e-04 8.6341605251930736e-04 +2.3738995348915562e-02 8.0295695579126886e-03 3.0015229767897395e-04 8.6942632367731127e-04 +2.3952623695161605e-02 6.5062795212043603e-03 2.6699673709128122e-04 8.7638665668172511e-04 +2.4168174493038350e-02 6.5390651424043775e-03 2.7155371818985959e-04 8.8312396312905305e-04 +2.4385665042779302e-02 6.4617205382751352e-03 2.7014672755448684e-04 8.8970775253373595e-04 +2.4605112800303586e-02 6.1242708291963897e-03 2.6232612988914415e-04 8.9720927091643278e-04 +2.4826535378616954e-02 5.6793862370787991e-03 2.5669323342458771e-04 9.0347421490645648e-04 +2.5049950549225465e-02 5.1137524674573992e-03 2.4744685919525034e-04 9.1013595608878698e-04 +2.5275376243561798e-02 5.0715281507510640e-03 2.4661133778676296e-04 9.1864323525257569e-04 +2.5502830554424420e-02 5.0378112186348443e-03 2.4704513388133591e-04 9.2548657511316824e-04 +2.5732331737429767e-02 4.5523100036128760e-03 2.3919340850292169e-04 9.3173438829395562e-04 +2.5963898212477448e-02 4.0075887730517063e-03 2.2259605356545533e-04 9.4002091588991140e-04 +2.6197548565228601e-02 4.3538688398406869e-03 2.3396091018105050e-04 9.4666848305364950e-04 +2.6433301548597618e-02 4.5772645541576765e-03 2.4115707990622463e-04 9.5422910073401305e-04 +2.6671176084257259e-02 3.7595255345007038e-03 2.1931146799267310e-04 9.6341084984366619e-04 +2.6911191264157329e-02 3.4687751333548331e-03 2.1130706788376251e-04 9.7025365591636725e-04 +2.7153366352056972e-02 3.4280294251800374e-03 2.1117047636182585e-04 9.7603991937129345e-04 +2.7397720785070828e-02 3.0988098018301588e-03 2.0353253305151864e-04 9.8405212963986570e-04 +2.7644274175229053e-02 3.0631097653504601e-03 2.0025279738740751e-04 9.9071870063870832e-04 +2.7893046311051387e-02 2.6189507808044949e-03 1.8972012884168663e-04 9.9848441599317676e-04 +2.8144057159135413e-02 2.7670387551085546e-03 1.9431921443520219e-04 1.0072117386581893e-03 +2.8397326865759069e-02 2.5745698827701236e-03 1.8831868298433725e-04 1.0106453741284542e-03 +2.8652875758497592e-02 2.7905681789483642e-03 1.9735568291361536e-04 1.0206108783355101e-03 +2.8910724347855053e-02 2.2579498616464998e-03 1.8144168545649193e-04 1.0247286452242205e-03 +2.9170893328910506e-02 2.2718397646608662e-03 1.8507254277329277e-04 1.0284513133486230e-03 +2.9433403582979002e-02 2.0913335375318648e-03 1.7730493232883838e-04 1.0347765664821713e-03 +2.9698276179287553e-02 2.0037579736302677e-03 1.7397641847780328e-04 1.0407227158837906e-03 +2.9965532376666153e-02 2.0053082414414943e-03 1.8148425060825760e-04 1.0471416121277033e-03 +3.0235193625253991e-02 1.8892278671415810e-03 1.7691505421149438e-04 1.0538028705339444e-03 +3.0507281568221079e-02 1.6455571663803511e-03 1.6438306782146591e-04 1.0586732890518317e-03 +3.0781818043505368e-02 2.0152345002365500e-03 1.8668060953165212e-04 1.0651681484471396e-03 +3.1058825085565428e-02 1.4399014212171631e-03 1.6141275114956683e-04 1.0740831689914773e-03 +3.1338324927148969e-02 1.7036160263742333e-03 1.7395184489677181e-04 1.0788999220164093e-03 +3.1620340001077260e-02 1.1217298551618442e-03 1.4542794260526752e-04 1.0852190174050710e-03 +3.1904892942045598e-02 1.6760876765263965e-03 1.8329924377565878e-04 1.0936302747601016e-03 +3.2192006588439973e-02 1.4541359774942839e-03 1.7112578883105698e-04 1.1006572678515826e-03 +3.2481703984170079e-02 1.2875872140922125e-03 1.5948329784556213e-04 1.1074818246421499e-03 +3.2774008380518888e-02 1.0770163414102337e-03 1.4904188037172727e-04 1.1115157833241759e-03 +3.3068943238008706e-02 1.0239128298757724e-03 1.4722523545267687e-04 1.1210080748372785e-03 +3.3366532228284257e-02 1.3048175654721734e-03 1.7133632525039643e-04 1.1281079743235417e-03 +3.3666799236012505e-02 7.8081362277807726e-04 1.3505100592578191e-04 1.1355989313283469e-03 +3.3969768360799638e-02 8.8962543191568346e-04 1.4347746193817939e-04 1.1448622805880508e-03 +3.4275463919125379e-02 5.8492135802313194e-04 1.1805992819084637e-04 1.1518871164758397e-03 +3.4583910446294566e-02 1.0037626448930780e-03 1.6184361791870929e-04 1.1590405080415585e-03 +3.4895132698406453e-02 9.7543464716695215e-04 1.5700708673043159e-04 1.1668900430769433e-03 +3.5209155654341573e-02 8.2897549415443853e-04 1.4987388458057805e-04 1.1754731914395710e-03 +3.5526004517766607e-02 5.7239932166676844e-04 1.2530670507033206e-04 1.1835062045421057e-03 +3.5845704719157254e-02 6.0909326959586723e-04 1.3776867520875599e-04 1.1899729621591166e-03 +3.6168281917839239e-02 8.8693445320398674e-04 1.6875462952929237e-04 1.2003910698861150e-03 +3.6493762004047754e-02 6.2866063571478806e-04 1.3770801746981355e-04 1.2069214028710526e-03 +3.6822171101005483e-02 7.2420676686636156e-04 1.5522563136825894e-04 1.2167722868909683e-03 +3.7153535567019239e-02 6.0486200606272840e-04 1.4335868693002909e-04 1.2240064922834871e-03 +3.7487881997595465e-02 4.9446798541633616e-04 1.3838616735761618e-04 1.2336892832317771e-03 +3.7825237227574859e-02 5.8215581368609181e-04 1.4606820653814031e-04 1.2427557293899095e-03 +3.8165628333286086e-02 4.8799461496087536e-04 1.4205352618575168e-04 1.2515238172612596e-03 +3.8509082634719000e-02 6.7630231365165602e-04 1.6475492676418794e-04 1.2596638429171289e-03 +3.8855627697717332e-02 3.8561873170820743e-04 1.2952940536673275e-04 1.2691388444112553e-03 +3.9205291336191161e-02 4.1438409638717576e-04 1.3132903286872680e-04 1.2796078996929498e-03 +3.9558101614349250e-02 3.1830759029369065e-04 1.2110370479995612e-04 1.2920115664439001e-03 +3.9914086848951529e-02 5.6771195393483416e-04 1.6471361196844844e-04 1.3001318282913159e-03 +4.0273275611581782e-02 2.1375692518747785e-04 1.0705467399039935e-04 1.3082872057334817e-03 +4.0635696730940848e-02 4.5930344831629293e-04 1.5326244166342880e-04 1.3154555503861233e-03 +4.1001379295160359e-02 4.2122812388616657e-04 1.4899195442700177e-04 1.3261958685364048e-03 +4.1370352654137479e-02 5.0335754311600276e-04 1.6788562790991915e-04 1.3332333052413590e-03 +4.1742646421890482e-02 2.3558363811391621e-04 1.1804725653138095e-04 1.3435013294740446e-03 +4.2118290478935588e-02 6.0136228364515883e-04 2.0124632978611175e-04 1.3516355545853918e-03 +4.2497314974685209e-02 3.4973579458410191e-04 1.5666145956338512e-04 1.3607785943180531e-03 +4.2879750329867759e-02 3.8041576943784828e-04 1.7040036063109117e-04 1.3704800464320716e-03 +4.3265627238969193e-02 1.4956829106560899e-04 1.0577627788060906e-04 1.3811467445739348e-03 +4.3654976672696626e-02 5.2457236348972601e-04 2.1438329194891435e-04 1.3893380463826904e-03 +4.4047829880464046e-02 3.5772420454280963e-04 1.7907266100853451e-04 1.3986637127843060e-03 +4.4444218392900400e-02 1.9663401121448377e-04 1.3931442465193813e-04 1.4087204853440356e-03 +4.4844174024380276e-02 6.3375339418640501e-04 2.5910150759841130e-04 1.4171719936303924e-03 +4.5247728875577285e-02 1.9911713936503233e-04 1.4079740927647961e-04 1.4297107977552753e-03 +4.5654915336040547e-02 3.5358306852108451e-04 2.0460404177313448e-04 1.4388379325034240e-03 +4.6065766086794288e-02 3.5432656021929464e-04 2.0464934542952718e-04 1.4487444072325503e-03 +4.6480314102960781e-02 2.8770257297080278e-04 2.0345856667102854e-04 1.4587365148404951e-03 +4.6898592656407043e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.4689492392730790e-03 +4.7320635318415155e-02 1.7033604000696743e-04 1.7033604000696740e-04 1.4785079554828448e-03 +4.7746475962376814e-02 5.6604272028629654e-04 3.2689578616413662e-04 1.4892584671520415e-03 +4.8176148766511939e-02 1.9739099846253179e-04 1.9739099846253182e-04 1.4994645342843837e-03 +4.8609688216611859e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5106514637331777e-03 +4.9047129108807180e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5225005846333374e-03 +4.9488506552360575e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5342463017077742e-03 +4.9933855972484620e-02 4.0777098120311518e-04 4.0777098120311508e-04 1.5465102660743115e-03 +5.0383213113185062e-02 9.6712777624285962e-04 6.8386581951956297e-04 1.5578312155554435e-03 +5.0836614040129652e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5687794057255237e-03 +5.1294095143542787e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5766818520382530e-03 +5.1755693141126241e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.5865994314325019e-03 +5.2221445081006082e-02 1.6425834058987397e-03 1.6425834058987399e-03 1.5961999224356393e-03 +5.2691388344706297e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.6063526892327405e-03 +5.3165560650148949e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.6164111412755033e-03 +5.3644000054681451e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.6284421571881489e-03 +5.4126744958131107e-02 0.0000000000000000e+00 0.0000000000000000e+00 1.6364407191857197e-03 diff --git a/tests/test_bayesian.py b/tests/test_bayesian.py new file mode 100644 index 00000000..15404645 --- /dev/null +++ b/tests/test_bayesian.py @@ -0,0 +1,476 @@ +# SPDX-FileCopyrightText: 2026 EasyReflectometry contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Tests for the Bayesian analysis module.""" + +import numpy as np +import pytest + + +@pytest.fixture +def sample_draws(): + """Generate synthetic posterior draws for testing.""" + rng = np.random.default_rng(42) + n_samples = 100 + # Two parameters: 'thickness' and 'sld' + thickness = rng.normal(loc=250, scale=10, size=n_samples) + sld = rng.normal(loc=2.0, scale=0.2, size=n_samples) + draws = np.column_stack([thickness, sld]) + param_names = ['Film_thickness', 'Film_sld'] + return draws, param_names + + +class TestPosteriorSummary: + def test_returns_string(self, sample_draws): + from easyreflectometry.analysis.bayesian import posterior_summary + + draws, param_names = sample_draws + result = posterior_summary(draws, param_names) + assert isinstance(result, str) + assert 'parameter' in result + assert 'mean' in result + assert 'sd' in result + + def test_header_uses_quantile_labels(self, sample_draws): + """The header should label the columns as equal-tailed quantiles, not HDI.""" + from easyreflectometry.analysis.bayesian import posterior_summary + + draws, param_names = sample_draws + result = posterior_summary(draws, param_names) + header = result.splitlines()[0] + assert 'q2.5%' in header + assert 'q97.5%' in header + assert 'hdi' not in header.lower() + + def test_contains_param_names(self, sample_draws): + from easyreflectometry.analysis.bayesian import posterior_summary + + draws, param_names = sample_draws + result = posterior_summary(draws, param_names) + for name in param_names: + assert name in result + + +class TestCredibleIntervals: + def test_returns_dict(self, sample_draws): + from easyreflectometry.analysis.bayesian import credible_intervals + + draws, param_names = sample_draws + result = credible_intervals(draws, param_names) + assert isinstance(result, dict) + for name in param_names: + assert name in result + lo, hi = result[name] + assert lo < hi + + def test_alpha_95_coverage(self, sample_draws): + from easyreflectometry.analysis.bayesian import credible_intervals + + draws, param_names = sample_draws + result = credible_intervals(draws, param_names, alpha=0.95) + for i, name in enumerate(param_names): + lo, hi = result[name] + # 95% interval should contain at least 90% of samples + col = draws[:, i] + inside = np.sum((col >= lo) & (col <= hi)) + assert inside / len(col) >= 0.90 + + def test_alpha_50_narrower(self, sample_draws): + from easyreflectometry.analysis.bayesian import credible_intervals + + draws, param_names = sample_draws + ci_95 = credible_intervals(draws, param_names, alpha=0.95) + ci_50 = credible_intervals(draws, param_names, alpha=0.50) + for name in param_names: + assert (ci_95[name][1] - ci_95[name][0]) > (ci_50[name][1] - ci_50[name][0]) + + +class TestPosteriorResults: + def test_repr(self, sample_draws): + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names) + rep = repr(pr) + assert 'PosteriorResults' in rep + assert str(draws.shape[0]) in rep + + def test_summary_delegates(self, sample_draws): + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names) + summary_str = pr.summary() + assert isinstance(summary_str, str) + assert 'parameter' in summary_str + + def test_credible_interval_delegates(self, sample_draws): + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names) + ci = pr.credible_interval(alpha=0.95) + assert isinstance(ci, dict) + for name in param_names: + assert name in ci + + +class TestPosteriorPredictiveReflectivity: + def test_returns_tuples(self, sample_draws): + """Test with a mock model that returns a constant array.""" + from unittest.mock import MagicMock + + from easyreflectometry.analysis.bayesian import posterior_predictive_reflectivity + + draws, param_names = sample_draws + mock_model = MagicMock() + mock_model.unique_name = 'test_model' + mock_model.interface = MagicMock() + mock_model.interface.fit_func = MagicMock(return_value=np.ones(50)) + mock_model.get_parameters = MagicMock(return_value=[]) + + q_values = np.linspace(0.01, 0.3, 50) + median, lower, upper = posterior_predictive_reflectivity( + draws, + param_names, + mock_model, + q_values, + n_samples=20, + ) + assert median.shape == (50,) + assert lower.shape == (50,) + assert upper.shape == (50,) + + +class TestPosteriorPredictiveSLDProfile: + def test_returns_tuples(self, sample_draws): + """Test with a mock model that returns constant z and sld.""" + from unittest.mock import MagicMock + + from easyreflectometry.analysis.bayesian import posterior_predictive_sld_profile + + draws, param_names = sample_draws + mock_model = MagicMock() + mock_model.unique_name = 'test_model' + mock_model.interface = MagicMock() + mock_model.interface.sld_profile = MagicMock(return_value=(np.linspace(0, 500, 100), np.ones(100) * 2.0)) + mock_model.get_parameters = MagicMock(return_value=[]) + + z, median, lower, upper = posterior_predictive_sld_profile( + draws, + param_names, + mock_model, + n_samples=20, + ) + assert z.shape == (100,) + assert median.shape == (100,) + assert lower.shape == (100,) + assert upper.shape == (100,) + + +class TestCornerPlot: + def test_plot_corner_returns_plotly_figure(self, sample_draws): + """plot_corner returns a Plotly Figure built from posterior draws.""" + try: + from plotly.graph_objects import Figure + + from easyreflectometry.analysis.bayesian import plot_corner + except ImportError: + pytest.skip('plotly not installed') + + draws, param_names = sample_draws + fig = plot_corner(draws, param_names) + assert isinstance(fig, Figure) + assert len(fig.data) > 0 + + +class TestSaveRestoreParameterState: + def test_save_and_restore(self): + """Test that parameter state save/restore works correctly.""" + from easyreflectometry.analysis.bayesian import _restore_parameter_state + from easyreflectometry.analysis.bayesian import _save_parameter_state + + # Use simple objects that support attribute assignment + class MockParam: + def __init__(self, unique_name, raw_value, error): + self.unique_name = unique_name + self.value = raw_value + self.error = error + + param1 = MockParam('param_a', 1.5, 0.1) + param2 = MockParam('param_b', 3.0, 0.2) + + class MockModel: + def get_parameters(self): + return [param1, param2] + + model = MockModel() + + state = _save_parameter_state(model) + assert state['param_a'] == (1.5, 0.1) + assert state['param_b'] == (3.0, 0.2) + + # Modify values + param1.raw_value = 99.0 + param1.value = 99.0 + param2.raw_value = 99.0 + param2.value = 99.0 + + _restore_parameter_state(model, state) + assert param1.value == 1.5 + assert param1.error == 0.1 + assert param2.value == 3.0 + assert param2.error == 0.2 + + +class TestApplyDraw: + def test_apply_draw_updates_parameters(self): + """Test that _apply_draw sets parameter values correctly.""" + from easyreflectometry.analysis.bayesian import _apply_draw + + class MockParam: + def __init__(self, unique_name): + self.unique_name = unique_name + self.value = None + + param_a = MockParam('thickness') + param_b = MockParam('sld') + + class MockModel: + def get_parameters(self): + return [param_a, param_b] + + model = MockModel() + draws = np.array([[250.0, 2.0], [260.0, 2.1]]) + param_names = ['thickness', 'sld'] + + _apply_draw(model, draws, param_names, row=0) + assert param_a.value == 250.0 + assert param_b.value == 2.0 + + _apply_draw(model, draws, param_names, row=1) + assert param_a.value == 260.0 + assert param_b.value == 2.1 + + +class TestGelmanRubinRequiresMultipleChains: + def test_raises_on_2d_draws(self, sample_draws): + """R-hat is undefined for a single chain; ``gelman_rubin`` must reject 2-D input.""" + pytest.importorskip('arviz') + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws # shape (n_samples, n_params) + pr = PosteriorResults(draws, param_names) + with pytest.raises(ValueError, match='at least 2 chains'): + pr.gelman_rubin() + + def test_raises_on_single_chain_3d(self, sample_draws): + """Even with an explicit chain axis, n_chains == 1 must raise.""" + pytest.importorskip('arviz') + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + single_chain = draws[np.newaxis, ...] # (1, n_draws, n_params) + pr = PosteriorResults(single_chain, param_names) + with pytest.raises(ValueError, match='at least 2 chains'): + pr.gelman_rubin() + + def test_accepts_multi_chain(self, sample_draws, monkeypatch): + """With n_chains >= 2 the diagnostic should forward to arviz and return its values.""" + pytest.importorskip('arviz') + from easyreflectometry.analysis import bayesian as bayesian_mod + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + rng = np.random.default_rng(7) + second = np.column_stack([ + rng.normal(loc=250, scale=10, size=draws.shape[0]), + rng.normal(loc=2.0, scale=0.2, size=draws.shape[0]), + ]) + multi = np.stack([draws, second], axis=0) # (2, n_draws, n_params) + + # Stub arviz.rhat so the test verifies the wrapper's contract (≥2 chains + # accepted, results unpacked per parameter) without depending on arviz's + # small-sample numerics, which can raise platform-specific TypeErrors. + class _FakeRhatVar: + def __init__(self, value: float) -> None: + self.values = np.array(value) + + fake_rhat = {name: _FakeRhatVar(1.01 + 0.001 * i) for i, name in enumerate(param_names)} + monkeypatch.setattr(bayesian_mod._arviz, 'rhat', lambda _data: fake_rhat) + + pr = PosteriorResults(multi, param_names) + result = pr.gelman_rubin() + assert isinstance(result, dict) + for i, name in enumerate(param_names): + assert name in result + assert result[name] == pytest.approx(1.01 + 0.001 * i) + + +class TestPlotFigureFallbackWarnings: + """When ``return_figure=True`` and plotly is missing, the helpers must warn.""" + + def test_plot_trace_warns_without_plotly(self, sample_draws, monkeypatch): + import builtins + + from easyreflectometry.analysis.bayesian import plot_trace + + real_import = builtins.__import__ + + def _fake_import(name, *args, **kwargs): + if name.startswith('plotly'): + raise ImportError('plotly disabled for test') + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, '__import__', _fake_import) + + draws, param_names = sample_draws + with pytest.warns(UserWarning, match='plotly'): + result = plot_trace(draws, param_names, return_figure=True) + assert result is None + + def test_plot_distribution_warns_without_plotly(self, sample_draws, monkeypatch): + import builtins + + from easyreflectometry.analysis.bayesian import plot_distribution + + real_import = builtins.__import__ + + def _fake_import(name, *args, **kwargs): + if name.startswith('plotly'): + raise ImportError('plotly disabled for test') + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, '__import__', _fake_import) + + draws, param_names = sample_draws + with pytest.warns(UserWarning, match='plotly'): + result = plot_distribution(draws, param_names, return_figure=True) + assert result is None + + +# =================================================================== +# Persistence helpers — save_posterior / load_posterior +# =================================================================== + + +class TestSaveLoadPosterior: + """Tests for ``save_posterior`` and ``load_posterior``.""" + + @pytest.fixture + def mock_posterior_results(self, sample_draws): + """Build a PosteriorResults with a real-looking mocked sampler_state.""" + from unittest.mock import MagicMock + + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + + # Build a mock that passes isinstance(obj, MCMCDraw) for the + # type guard in save_posterior. We use a non-spec MagicMock and + # reassign its __class__ so isinstance succeeds. + import bumps.dream.state as _bds + + mock_state = MagicMock() + mock_state.__class__ = _bds.MCMCDraw + + mock_state.Nvar = draws.shape[1] + mock_state.Npop = 5 + mock_state.labels = [f'p{name}' for name in param_names] + mock_draw = MagicMock() + mock_draw.points = draws + mock_draw.logp = np.zeros(draws.shape[0]) + mock_state.draw.return_value = mock_draw + + pr = PosteriorResults( + draws=draws, + param_names=param_names, + logp=np.zeros(draws.shape[0]), + sampler_state=mock_state, + ) + return pr + + def test_save_posterior_no_state_raises(self, sample_draws): + """PosteriorResults without sampler_state raises ValueError.""" + from easyreflectometry.analysis.bayesian import PosteriorResults + from easyreflectometry.analysis.bayesian import save_posterior + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names) + with pytest.raises(ValueError, match='no sampler_state'): + save_posterior(pr, 'dummy') + + def test_save_posterior_wrong_state_type_raises(self, sample_draws): + """Non-MCMCDraw sampler_state raises TypeError.""" + from unittest.mock import MagicMock + + from easyreflectometry.analysis.bayesian import PosteriorResults + from easyreflectometry.analysis.bayesian import save_posterior + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names, sampler_state=MagicMock()) + with pytest.raises(TypeError, match='MCMCDraw'): + save_posterior(pr, 'dummy') + + def test_save_and_load_roundtrip(self, mock_posterior_results, monkeypatch, tmp_path): + """Save then load, verify draws, param_names, logp, and state.""" + from unittest.mock import MagicMock + + # Mock save_state and load_state + import bumps.dream.state as _bds + + from easyreflectometry.analysis.bayesian import load_posterior + from easyreflectometry.analysis.bayesian import save_posterior + + saved_state_ref = mock_posterior_results.sampler_state + monkeypatch.setattr(_bds, 'save_state', MagicMock()) + monkeypatch.setattr(_bds, 'load_state', MagicMock(return_value=saved_state_ref)) + + prefix = str(tmp_path / 'test_run') + save_posterior(mock_posterior_results, prefix) + + # Verify save_state was called + _bds.save_state.assert_called_once_with(saved_state_ref, prefix) + + loaded = load_posterior(prefix) + + assert np.allclose(loaded.draws, mock_posterior_results.draws) + assert loaded.param_names == mock_posterior_results.param_names + assert loaded.sampler_state is saved_state_ref + + def test_save_convenience_method(self, mock_posterior_results, monkeypatch, tmp_path): + """PosteriorResults.save() delegates to save_posterior.""" + from unittest.mock import MagicMock + + import bumps.dream.state as _bds + + monkeypatch.setattr(_bds, 'save_state', MagicMock()) + + prefix = str(tmp_path / 'test_convenience') + mock_posterior_results.save(prefix) + + _bds.save_state.assert_called_once_with(mock_posterior_results.sampler_state, prefix) + + def test_load_posterior_skip(self, mock_posterior_results, monkeypatch, tmp_path): + """load_posterior with skip>0 forwards skip to load_state.""" + from unittest.mock import MagicMock + + import bumps.dream.state as _bds + + from easyreflectometry.analysis.bayesian import load_posterior + + monkeypatch.setattr(_bds, 'load_state', MagicMock(return_value=mock_posterior_results.sampler_state)) + monkeypatch.setattr(_bds, 'save_state', MagicMock()) + + prefix = str(tmp_path / 'test_skip') + load_posterior(prefix, skip=5) + + _bds.load_state.assert_called_once_with(prefix, skip=5) + + +class TestPlotDistributionExported: + def test_in_analysis_namespace(self): + """``plot_distribution`` should be importable from the analysis package.""" + from easyreflectometry import analysis + + assert hasattr(analysis, 'plot_distribution') + assert 'plot_distribution' in analysis.__all__ diff --git a/tests/test_fitting.py b/tests/test_fitting.py index 28dfe0fa..e4f938c8 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -801,3 +801,266 @@ def _fake_fit(*, x, y, weights): fitter.fit_single_data_set_1d(data, objective='legacy_mask') assert len(captured['x'][0]) == 2 # one point dropped + + +# --------------------------------------------------------------------------- +# Tests for MultiFitter.mcmc_sample (Bayesian MCMC) +# --------------------------------------------------------------------------- + + +class TestMCMCSampleRequiresBumpsEngine: + """mcmc_sample() must raise when the core engine is not a BUMPS instance.""" + + def test_raises_runtime_error_when_not_bumps(self): + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): + fitter.mcmc_sample(data) + + def test_wrapper_check_runs_before_core_mcmc_sample(self): + """The wrapper-level guard must fire before delegating to the core sampler. + + Replace the core ``mcmc_sample`` with a sentinel that would record any call; + the guard should raise without invoking it. + """ + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) # default minimizer is LMFit, not BUMPS + + core_called = {'count': 0} + + def _should_not_be_called(**_kwargs): + core_called['count'] += 1 + return {'draws': np.empty((0, 0)), 'param_names': [], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter.mcmc_sample = _should_not_be_called + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): + fitter.mcmc_sample(data) + assert core_called['count'] == 0 + + +class TestMCMCSampleBasic: + """Basic mcmc_sample() dispatch and return-value forwarding.""" + + def test_returns_core_result_dict(self): + """mcmc_sample() returns whatever the core MultiFitter.mcmc_sample() returns.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + # Mock the core MultiFitter.mcmc_sample to return a known dict + fake_result = {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(return_value=fake_result) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + result = fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=5) + assert result is fake_result + + def test_forwards_hyperparams_to_core(self): + """Samples, burn, thin, population, chains are forwarded to core.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + captured = {} + + def _fake_mcmc_sample(*, x, y, weights, samples, burn, thin, population, **kwargs): + captured['samples'] = samples + captured['burn'] = burn + captured['thin'] = thin + captured['population'] = population + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + fitter.mcmc_sample(data, samples=500, burn=100, thin=5, population=8) + assert captured['samples'] == 500 + assert captured['burn'] == 100 + assert captured['thin'] == 5 + assert captured['population'] == 8 + + def test_forwards_population_to_core(self): + """'population' argument is forwarded to core.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + captured = {} + + def _fake_mcmc_sample(*, x, y, weights, population, **kwargs): + captured['population'] = population + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=6) + assert captured['population'] == 6 + + +class TestMCMCSampleInitializer: + """initializer parameter is forwarded via sampler_kwargs.""" + + def test_initializer_passed_as_sampler_kwargs_init(self): + """initializer='lhs' should be passed as sampler_kwargs={'init': 'lhs'} to core.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + captured = {} + + def _fake_mcmc_sample(*, sampler_kwargs, **kwargs): + captured['sampler_kwargs'] = sampler_kwargs + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, initializer='lhs') + assert captured['sampler_kwargs'] == {'init': 'lhs'} + + def test_initializer_none_omits_sampler_kwargs(self): + """When initializer is None, sampler_kwargs should be None, not an empty dict.""" + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + captured = {} + + def _fake_mcmc_sample(*, sampler_kwargs, **kwargs): + captured['sampler_kwargs'] = sampler_kwargs + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, + }) + + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + assert captured['sampler_kwargs'] is None + + +class TestMCMCSampleZeroVariance: + """Zero-variance handling in the mcmc_sample() data-preparation path.""" + + def test_hybrid_transforms_zero_variance_points(self): + """mcmc_sample() uses the objective from constructor to prepare data arrays.""" + import warnings + + model = Model() + model.interface = CalculatorFactory() + # Use legacy_mask so zero-variance points are dropped + fitter = MultiFitter(model, objective='legacy_mask') + + captured = {} + + def _fake_mcmc_sample(*, x, y, weights, **kwargs): + captured['x'] = x + captured['y'] = y + captured['weights'] = weights + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + qz = np.linspace(0.01, 0.3, 10) + r = np.exp(-qz * 50) + var = np.ones(10) * 0.01 + var[3:5] = 0.0 # 2 zero-variance points + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r, variances=var)}, + }) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + + # legacy_mask should drop the 2 zero-variance points + assert len(captured['x'][0]) == 8 + assert len(captured['y'][0]) == 8 + assert len(captured['weights'][0]) == 8 + + mask_warnings = [str(ww.message) for ww in w if 'Masked' in str(ww.message)] + assert len(mask_warnings) == 1 + assert '2 data point(s)' in mask_warnings[0] + + def test_per_call_objective_override(self): + """mcmc_sample() respects per-call objective override.""" + import warnings + + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective='legacy_mask') # default + + captured = {} + + def _fake_mcmc_sample(*, x, y, weights, **kwargs): + captured['x'] = x + captured['y'] = y + return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + qz = np.linspace(0.01, 0.3, 10) + r = np.exp(-qz * 50) + var = np.ones(10) * 0.01 + var[3:5] = 0.0 + + data = sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r, variances=var)}, + }) + + # Override to hybrid — should keep all 10 points + with warnings.catch_warnings(record=True): + warnings.simplefilter('always') + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, objective='hybrid') + + assert len(captured['x'][0]) == 10 # all points kept (Mighell-substituted) diff --git a/tests/test_ort_file.py b/tests/test_ort_file.py index b1277033..ed8180df 100644 --- a/tests/test_ort_file.py +++ b/tests/test_ort_file.py @@ -2,14 +2,13 @@ # SPDX-License-Identifier: BSD-3-Clause import logging +import os import numpy as np - -# from dmsc_nightly.data import make_pooch -import pooch import pytest from easyscience.fitting import AvailableMinimizers +import easyreflectometry from easyreflectometry.calculators import CalculatorFactory from easyreflectometry.data import load from easyreflectometry.fitting import MultiFitter @@ -20,30 +19,12 @@ from easyreflectometry.sample import Multilayer from easyreflectometry.sample import Sample - -def make_pooch(base_url: str, registry: dict[str, str | None]) -> pooch.Pooch: - """Make a Pooch object to download test data.""" - return pooch.create( - path=pooch.os_cache('data'), - env='POOCH_DIR', - base_url=base_url, - registry=registry, - ) - - -@pytest.fixture(scope='module') -def data_registry(): - return make_pooch( - base_url='https://pub-6c25ef91903d4301a3338bd53b370098.r2.dev', - registry={ - 'amor_reduced_iofq.ort': None, - }, - ) +PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') @pytest.fixture(scope='module') -def load_data(data_registry): - path = data_registry.fetch('amor_reduced_iofq.ort') +def load_data(): + path = os.path.join(PATH_STATIC, 'amor_reduced_iofq.ort') logging.info('Loading data from %s', path) data = load(path) return data From bfae1449cc8ee2598d76809bd679a50916306bd7 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 5 Jun 2026 16:44:46 +0200 Subject: [PATCH 15/22] HTML Summary now shows plots with plotly (#363) --- pyproject.toml | 1 + .../summary/html_templates.py | 10 ++ src/easyreflectometry/summary/summary.py | 167 ++++++++++++++++-- tests/summary/test_summary.py | 21 ++- 4 files changed, 185 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e9a7c354..ac183b21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ dependencies = [ 'xhtml2pdf', 'bumps', 'pooch', + 'plotly', ] [project.optional-dependencies] diff --git a/src/easyreflectometry/summary/html_templates.py b/src/easyreflectometry/summary/html_templates.py index 66012d40..9df780aa 100644 --- a/src/easyreflectometry/summary/html_templates.py +++ b/src/easyreflectometry/summary/html_templates.py @@ -150,3 +150,13 @@
Fit experiment plot """ + +# Interactive figures for HTML reports. The plotly ``
``s carry their own +# JavaScript so the report stays interactive (zoom, pan, hover) when opened in a +# browser. The plotly.js library is embedded inline in the first figure, which +# keeps the saved report self-contained and working offline. +HTML_INTERACTIVE_FIGURES_TEMPLATE = """ +sld_plot_div +
+fit_experiment_plot_div +""" diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index 2fc2846f..f40f23ad 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -1,6 +1,9 @@ # SPDX-FileCopyrightText: 2024 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause +import contextlib +import io +import logging from html import escape from importlib.metadata import PackageNotFoundError from importlib.metadata import version @@ -15,12 +18,35 @@ from .html_templates import HTML_DATA_COLLECTION_TEMPLATE from .html_templates import HTML_FIGURES_TEMPLATE +from .html_templates import HTML_INTERACTIVE_FIGURES_TEMPLATE from .html_templates import HTML_PARAMETER_HEADER_TEMPLATE from .html_templates import HTML_PARAMETER_TEMPLATE from .html_templates import HTML_PROJECT_INFORMATION_TEMPLATE from .html_templates import HTML_REFINEMENT_TEMPLATE from .html_templates import HTML_TEMPLATE + +@contextlib.contextmanager +def _silence_pdf_converter(): + """Silence xhtml2pdf's verbose output during PDF conversion. + + xhtml2pdf emits a large amount of ``log.debug`` output (image tags, file + objects, column widths, parsed schemes, ...) and a few stray ``print`` + statements while rendering. When the host application has configured logging + at DEBUG level this floods stdout. For the duration of the conversion we + raise the ``xhtml2pdf`` logger level so its debug records are dropped, and + redirect stdout to swallow the stray prints. Both are restored afterwards. + """ + xhtml2pdf_logger = logging.getLogger('xhtml2pdf') + previous_level = xhtml2pdf_logger.level + xhtml2pdf_logger.setLevel(logging.WARNING) + try: + with contextlib.redirect_stdout(io.StringIO()): + yield + finally: + xhtml2pdf_logger.setLevel(previous_level) + + _NAME_MAX_LEN = 20 # Custom href scheme used to pass the full name to QML via TextEdit.hoveredLink. _TOOLTIP_SCHEME = 'nametooltip' @@ -89,8 +115,19 @@ def __init__(self, project: Project): """Init function.""" self._project = project - def compile_html_summary(self, figures: bool = False) -> str: - """Compile html summary.""" + def compile_html_summary(self, figures: bool = False, interactive: bool = True) -> str: + """Compile html summary. + + Parameters + ---------- + figures + Whether to render the figures section. + interactive + When ``True`` (the default) the figures are rendered as interactive + plotly charts suitable for an HTML report. Set to ``False`` to fall + back to static images, e.g. when the html is handed to the PDF + converter, which cannot run the embedded JavaScript. + """ html = HTML_TEMPLATE html = html.replace('project_information_section', self._project_information_section()) @@ -105,7 +142,7 @@ def compile_html_summary(self, figures: bool = False) -> str: html = html.replace('refinement_section', self._refinement_section()) if figures: - html = html.replace('figures_section', self._figures_section()) + html = html.replace('figures_section', self._figures_section(interactive=interactive)) else: html = html.replace('figures_section', '') @@ -113,19 +150,22 @@ def compile_html_summary(self, figures: bool = False) -> str: def save_html_summary(self, filename: str) -> None: """Save html summary.""" - html = self.compile_html_summary(figures=True) - with open(filename, 'w') as f: + html = self.compile_html_summary(figures=True, interactive=True) + with open(filename, 'w', encoding='utf-8') as f: f.write(html) def save_pdf_summary(self, filename: str) -> None: """Save pdf summary.""" - html = self.compile_html_summary(figures=True) + # The PDF converter (xhtml2pdf) cannot execute the JavaScript that powers + # the interactive plotly charts, so embed static images instead. + html = self.compile_html_summary(figures=True, interactive=False) with open(filename, 'w+b') as result_file: - pisa_status = pisa.CreatePDF( - html, - dest=result_file, - ) + with _silence_pdf_converter(): + pisa_status = pisa.CreatePDF( + html, + dest=result_file, + ) if pisa_status.err: print('An error occured when generating PDF summary!') @@ -290,8 +330,16 @@ def _compute_goodness_of_fit(self) -> str: except (AttributeError, TypeError, ValueError, ZeroDivisionError): return 'N/A' - def _figures_section(self) -> None: - """Figures section.""" + def _figures_section(self, interactive: bool = True) -> str: + """Figures section. + + When *interactive* is ``True`` the figures are rendered as interactive + plotly charts embedded directly in the html. Otherwise static images are + written to disk and referenced (used for the PDF report). + """ + if interactive: + return self._interactive_figures_section() + html_figures = HTML_FIGURES_TEMPLATE path_sld = self._project.path / 'sld_plot.jpg' path_fit_experiment = self._project.path / 'fit_experiment_plot.jpg' @@ -302,3 +350,98 @@ def _figures_section(self) -> None: html_figures = html_figures.replace('path_sld_plot', str(path_sld)) html_figures = html_figures.replace('path_fit_experiment_plot', str(path_fit_experiment)) return html_figures + + def _interactive_figures_section(self) -> str: + """Build the interactive (plotly) figures section for the html report.""" + import plotly.io as pio + + fig_sld = self._sld_plotly_figure() + fig_fit_experiment = self._fit_experiment_plotly_figure() + + # Embed plotly.js inline once (with the first figure) so the saved report + # is self-contained and renders without an internet connection. + sld_div = pio.to_html( + fig_sld, + include_plotlyjs=True, + full_html=False, + default_width='640px', + default_height='480px', + ) + fit_experiment_div = pio.to_html( + fig_fit_experiment, + include_plotlyjs=False, + full_html=False, + default_width='640px', + default_height='480px', + ) + + html_figures = HTML_INTERACTIVE_FIGURES_TEMPLATE + html_figures = html_figures.replace('sld_plot_div', sld_div) + html_figures = html_figures.replace('fit_experiment_plot_div', fit_experiment_div) + return html_figures + + def _sld_plotly_figure(self): + """Interactive SLD profile figure.""" + import plotly.graph_objects as go + + sld = self._project.sld_data_for_model_at_index(0) + + fig = go.Figure() + fig.add_trace( + go.Scatter( + x=np.asarray(sld.x), + y=np.asarray(sld.y), + mode='lines', + name='SLD', + line={'color': 'blue'}, + ) + ) + fig.update_layout( + xaxis_title='z (Å)', + yaxis_title='SLD (Å⁻²)', + template='simple_white', + margin={'l': 70, 'r': 20, 't': 30, 'b': 50}, + legend={'x': 0.99, 'xanchor': 'right', 'y': 0.99, 'yanchor': 'top'}, + ) + return fig + + def _fit_experiment_plotly_figure(self): + """Interactive reflectivity (model vs. experiment) figure.""" + import plotly.graph_objects as go + + fig = go.Figure() + + model = self._project.model_data_for_model_at_index(0) + fig.add_trace( + go.Scatter( + x=np.asarray(model.x), + y=np.asarray(model.y), + mode='lines', + name='Model', + line={'color': 'blue'}, + ) + ) + + try: + experiment = self._project.experimental_data_for_model_at_index(0) + fig.add_trace( + go.Scatter( + x=np.asarray(experiment.x), + y=np.asarray(experiment.y), + mode='markers', + name='Experiment', + marker={'color': 'red', 'size': 4}, + ) + ) + except IndexError: + pass + + fig.update_layout( + xaxis_title='Q (Å⁻¹)', + yaxis_title='Reflectivity', + yaxis_type='log', + template='simple_white', + margin={'l': 70, 'r': 20, 't': 30, 'b': 50}, + legend={'x': 0.99, 'xanchor': 'right', 'y': 0.99, 'yanchor': 'top'}, + ) + return fig diff --git a/tests/summary/test_summary.py b/tests/summary/test_summary.py index 8a8f581f..5f135fb0 100644 --- a/tests/summary/test_summary.py +++ b/tests/summary/test_summary.py @@ -195,17 +195,34 @@ def test_save_fit_experiment_plot(self, project: Project, tmp_path) -> None: # Expect assert os.path.exists(file_path) - def test_figures_section(self, project: Project) -> None: + def test_figures_section_static(self, project: Project) -> None: # When summary = Summary(project) summary.save_sld_plot = MagicMock() summary.save_fit_experiment_plot = MagicMock() # Then - html = summary._figures_section() + html = summary._figures_section(interactive=False) # Expect summary.save_sld_plot.assert_called_once() summary.save_fit_experiment_plot.assert_called_once() assert 'sld_plot' in html assert 'fit_experiment_plot' in html + + def test_figures_section_interactive(self, project: Project) -> None: + # When + summary = Summary(project) + summary.save_sld_plot = MagicMock() + summary.save_fit_experiment_plot = MagicMock() + + # Then + html = summary._figures_section(interactive=True) + + # Expect + # Interactive figures must not fall back to the static image plots. + summary.save_sld_plot.assert_not_called() + summary.save_fit_experiment_plot.assert_not_called() + # Two interactive plotly charts with the library embedded inline once. + assert html.count('class="plotly-graph-div"') == 2 + assert 'Plotly.newPlot' in html From a47241189d172f9197575e52133b634b84c27d6b Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 5 Jun 2026 17:20:04 +0200 Subject: [PATCH 16/22] Pointwise update (#362) * initial commit with examples * ruff format * refactor core modifications to live in reflectometry lib only * modified the notebook a bit * refactored MCMC sampling to easyscience module * added pass-through for cancellation and total number of calculations * silly typo * yet another linting * moved the notebook to the correct location and fixed the formatting * added more initial arguments to sample. Added unit tests * prettify charts. Updated notebook * fixed issue with the notebook * move file fetch to reflectometry/data * PR review fixes * be careful with small chains * ruff * try to use explicit dtype for Ubuntu * another attempt at fixing failing test * better corner and distribution plots * updated poitwise logic/notebook --- .../simulation/resolution_functions.ipynb | 11 ++- .../model/resolution_functions.py | 80 +++++++++---------- tests/model/test_resolution_functions.py | 15 +++- 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/docs/docs/tutorials/simulation/resolution_functions.ipynb b/docs/docs/tutorials/simulation/resolution_functions.ipynb index b5bd017e..d46a76cb 100644 --- a/docs/docs/tutorials/simulation/resolution_functions.ipynb +++ b/docs/docs/tutorials/simulation/resolution_functions.ipynb @@ -340,7 +340,10 @@ "## Afterthoughts\n", "As a last task we will compare the reflectivity determined using a percentage resolution function and a point-wise function.\n", "We should recall that the \"experimental\" data was generated using `Refnx`.\n", - "By comparing the reflectivities determined using a resolution function with a FWHM of 1.0% and the point-wise FHWN constructed from data in a `.ort` file it is apparent that this reference data also was constructed using a resolution function of 1.0%." + "\n", + "The `Pointwise` resolution function derives a per-point resolution width directly from the data: it takes the `[Qz, R, sQz]` triple, where `sQz` is the variance of `Qz` (`Qz_0.variances`), and uses `sqrt(sQz)` as the resolution width at each measured point, linearly interpolating onto the requested `q` (exactly as `LinearSpline` does for explicitly provided widths).\n", + "\n", + "By comparing the reflectivities determined using a resolution function with a FWHM of 1.0% and the point-wise width constructed from the data in a `.ort` file, it is apparent that this reference data also was constructed using a resolution function of 1.0%." ] }, { @@ -404,16 +407,20 @@ " model.unique_name,\n", ")\n", "plt.plot(model_coords, model_data, 'k-', label='Variable', linewidth=5)\n", + "\n", + "# The Pointwise resolution is built from the data triple [Qz, R, sQz],\n", + "# where sQz is the variance of Qz. The width sqrt(sQz) is interpolated onto q.\n", "data_points = []\n", "data_points.append(reference_coords) # Qz\n", "data_points.append(reference_data) # R\n", - "data_points.append(reference_variances) # sQz\n", + "data_points.append(reference_variances) # sQz (variance of Qz)\n", "model.resolution_function = Pointwise(q_data_points=data_points)\n", "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", "plt.plot(model_coords, model_data, 'r-', label='Pointwise')\n", + "plt.plot(reference_coords, reference_data, 'bx', label='Reference', markersize=4)\n", "\n", "ax = plt.gca()\n", "ax.set_xlim([-0.01, 0.45])\n", diff --git a/src/easyreflectometry/model/resolution_functions.py b/src/easyreflectometry/model/resolution_functions.py index ee0933e2..fe5d2254 100644 --- a/src/easyreflectometry/model/resolution_functions.py +++ b/src/easyreflectometry/model/resolution_functions.py @@ -82,27 +82,45 @@ def as_dict( } -# add pointwise smearing funtion class Pointwise(ResolutionFunction): - def __init__(self, q_data_points: list[np.ndarray]): - """Init function.""" + """Pointwise resolution defined by a per-point resolution provided with the data. + + The resolution is supplied as the variance of the Qz values (``sQz``) at the + measured Qz data points, which is the form produced by data reduction (e.g. + ``Qz_0.variances``). The resolution width at each point is ``sqrt(sQz)``. + For a requested ``q`` the width is obtained by linearly interpolating onto + ``q``, exactly as :class:`LinearSpline` does for explicitly provided widths. + + This is a convenience wrapper around :class:`LinearSpline` that derives the + widths from the ``[Qz, R, sQz]`` triple loaded from a data file; the returned + widths are consumed by the calculators (refnx ``x_err`` / refl1d ``dq``), + which perform the actual convolution against the model. + """ + + def __init__(self, q_data_points: List[np.ndarray]): + """Init function. + + Parameters + ---------- + q_data_points : List[np.ndarray] + ``[Qz, R, sQz]`` where ``Qz`` are the measured Qz values, ``R`` the + measured reflectivity (kept only for serialization round-trips) and + ``sQz`` the variance of ``Qz`` at each point. + """ self.q_data_points = q_data_points - self.q = None - def smearing(self, q: Union[np.ndarray, float] = None) -> np.ndarray: - """Smearing function.""" - Qz = self.q_data_points[0] - R = self.q_data_points[1] - sQz = self.q_data_points[2] - if q is None: - q = self.q_data_points[0] - self.q = q - sQzs = np.sqrt(sQz) - if isinstance(Qz, float): - Qz = np.array(Qz) - - smeared = self.apply_smooth_smearing(Qz, R, sQzs) - return smeared + def smearing(self, q: Optional[Union[np.ndarray, float]] = None) -> np.ndarray: + """Return the resolution width interpolated onto ``q``. + + The width at each data point is ``sqrt(sQz)``; values are linearly + interpolated onto the requested ``q``. When ``q`` is ``None`` the widths + are returned at the stored data points. + """ + Qz = np.asarray(self.q_data_points[0], dtype=float) + sQz = np.asarray(self.q_data_points[2], dtype=float) + q_eval = Qz if q is None else np.asarray(q, dtype=float) + widths = np.sqrt(sQz) + return np.asarray(np.interp(q_eval, Qz, widths)) def as_dict( self, skip: Optional[List[str]] = None @@ -114,29 +132,3 @@ def as_dict( 'R_data_points': list(self.q_data_points[1]), 'sQz_data_points': list(self.q_data_points[2]), } - - def gaussian_smearing(self, qt, Qz, R, sQz): - """Gaussian smearing.""" - weights = np.exp(-0.5 * ((qt - Qz) / sQz) ** 2) - if np.sum(weights) == 0 or not np.isfinite(np.sum(weights)): - return np.sum(R) - weights /= sQz * np.sqrt(2 * np.pi) - return np.sum(R * weights) / np.sum(weights) - - def apply_smooth_smearing(self, Qz, R, sQzs): - """Apply smooth resolution smearing using convolution with Gaussian kernel.""" - if self.q is None: - R_smeared = np.zeros_like(Qz) - else: - R_smeared = np.zeros_like(self.q) - - if not isinstance(Qz, np.ndarray): - Qz = np.array(Qz) - if not isinstance(R, np.ndarray): - R = np.array(R) - R_smeared = np.zeros_like(self.q) - - for i, qt in enumerate(self.q): - R_smeared[i] = self.gaussian_smearing(qt, Qz, R, sQzs) - - return R_smeared diff --git a/tests/model/test_resolution_functions.py b/tests/model/test_resolution_functions.py index e28a99f2..b8a4ea18 100644 --- a/tests/model/test_resolution_functions.py +++ b/tests/model/test_resolution_functions.py @@ -95,12 +95,23 @@ def test_constructor(self): # When resolution_function = Pointwise(q_data_points=self.data_points) - # Then Expect + # Then Expect: smearing returns the resolution width sqrt(sQz) at the data + # points, since sQz holds the variance of Qz (consistent with LinearSpline). + expected_widths = np.sqrt(self.data_points[2]) assert np.allclose( np.array(resolution_function.smearing()), - np.array([2.51664683, 2.84038734, 3.2460762, 3.6796519, 4.07869271]), + expected_widths, ) + def test_smearing_interpolates_onto_q(self): + # When + resolution_function = Pointwise(q_data_points=self.data_points) + + # Then Expect: requesting points between data points linearly interpolates the width. + widths = np.sqrt(self.data_points[2]) + expected = np.interp([0.15, 0.25], self.data_points[0], widths) + assert np.allclose(resolution_function.smearing([0.15, 0.25]), expected) + def test_as_dict(self): # When resolution_function = Pointwise(q_data_points=self.data_points) From 5e14e7fe9d2af7b3669ede3ab5fc58184f2efe6e Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 24 Jul 2026 10:14:06 +0200 Subject: [PATCH 17/22] 381 apitest hygiene (#384) * addressing #381 * minor docstring update --- CONTRIBUTING.md | 3 +- docs/docs/tutorials/simulation/bilayer.ipynb | 10 +-- .../docs/tutorials/simulation/magnetism.ipynb | 16 ++--- .../simulation/resolution_functions.ipynb | 10 +-- docs/mkdocs.yml | 3 +- pixi.lock | 66 +++++++++++-------- .../calculators/calculator_base.py | 2 +- src/easyreflectometry/calculators/factory.py | 2 +- src/easyreflectometry/fitting.py | 20 +----- src/easyreflectometry/limits.py | 11 +++- src/easyreflectometry/model/model.py | 4 +- .../model/resolution_functions.py | 3 +- src/easyreflectometry/project.py | 44 ++++++------- .../elements/materials/material_mixture.py | 17 +++-- src/easyreflectometry/special/calculations.py | 10 +-- .../refl1d/test_refl1d_calculator.py | 8 +-- .../refnx/test_refnx_calculator.py | 6 +- tests/model/test_model.py | 4 +- tests/model/test_resolution_functions.py | 11 +++- .../layers/test_layer_area_per_molecule.py | 18 ++--- .../materials/test_material_mixture.py | 58 ++++++++-------- tests/test_project.py | 2 +- tests/test_topmost_nesting.py | 4 +- 23 files changed, 171 insertions(+), 161 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a4ac1fbc..a6ceeebd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,8 +42,7 @@ Please make sure you follow the EasyScience organization-wide If you are not planning to contribute code, you may want to: - 🐞 Report a bug — see [Reporting Issues](#11-reporting-issues) -- 🛡 Report a security issue — see - [Security Issues](#12-security-issues) +- 🛡 Report a security issue — see [Security Issues](#12-security-issues) - 💬 Ask a question or start a discussion at [Project Discussions](https://github.com/easyscience/reflectometry-lib/discussions) diff --git a/docs/docs/tutorials/simulation/bilayer.ipynb b/docs/docs/tutorials/simulation/bilayer.ipynb index 5f37b010..987cd8e1 100644 --- a/docs/docs/tutorials/simulation/bilayer.ipynb +++ b/docs/docs/tutorials/simulation/bilayer.ipynb @@ -331,7 +331,7 @@ "q = np.linspace(0.005, 0.3, 500)\n", "\n", "# Calculate reflectometry\n", - "reflectivity = model.interface().reflectity_profile(q, model.unique_name)\n", + "reflectivity = model.interface().reflectivity_profile(q, model.unique_name)\n", "\n", "# Plot\n", "plt.figure(figsize=(10, 6))\n", @@ -391,7 +391,7 @@ "outputs": [], "source": [ "# First, compute reflectivity with current conformal roughness (3.0 Å)\n", - "reflectivity_conformal = model.interface().reflectity_profile(q, model.unique_name)\n", + "reflectivity_conformal = model.interface().reflectivity_profile(q, model.unique_name)\n", "\n", "# Disable conformal roughness to allow independent roughness per layer\n", "bilayer.conformal_roughness = False\n", @@ -406,7 +406,7 @@ "bilayer.back_head_layer.roughness.value = 4.0\n", "\n", "# Compute reflectivity with variable roughness\n", - "reflectivity_variable_roughness = model.interface().reflectity_profile(q, model.unique_name)\n", + "reflectivity_variable_roughness = model.interface().reflectivity_profile(q, model.unique_name)\n", "\n", "# Plot comparison\n", "plt.figure(figsize=(10, 6))\n", @@ -629,8 +629,8 @@ "outputs": [], "source": [ "# Calculate reflectivity for both contrasts\n", - "reflectivity_d2o = model.interface().reflectity_profile(q, model.unique_name)\n", - "reflectivity_h2o = model_h2o.interface().reflectity_profile(q, model_h2o.unique_name)\n", + "reflectivity_d2o = model.interface().reflectivity_profile(q, model.unique_name)\n", + "reflectivity_h2o = model_h2o.interface().reflectivity_profile(q, model_h2o.unique_name)\n", "\n", "plt.figure(figsize=(10, 6))\n", "plt.semilogy(q, reflectivity_d2o, 'b-', linewidth=2, label='D₂O contrast')\n", diff --git a/docs/docs/tutorials/simulation/magnetism.ipynb b/docs/docs/tutorials/simulation/magnetism.ipynb index 8efdb9e4..ef226c41 100644 --- a/docs/docs/tutorials/simulation/magnetism.ipynb +++ b/docs/docs/tutorials/simulation/magnetism.ipynb @@ -252,7 +252,7 @@ "model.resolution_function = PercentageFwhm(0)\n", "model_interface = model.interface()\n", "model_interface.magnetism = False\n", - "model_data_no_magnetism_ref1d_easy = model.interface().reflectity_profile(\n", + "model_data_no_magnetism_ref1d_easy = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -284,7 +284,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.include_magnetism = True\n", - "model_data_magnetism = model.interface().reflectity_profile(\n", + "model_data_magnetism = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -301,7 +301,7 @@ "model_interface._wrapper.update_layer(\n", " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", ")\n", - "model_data_magnetism_layer_1 = model.interface().reflectity_profile(\n", + "model_data_magnetism_layer_1 = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -365,7 +365,7 @@ "model_interface._wrapper.update_layer(\n", " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", ")\n", - "model_data_magnetism_easy = model.interface().reflectity_profile(\n", + "model_data_magnetism_easy = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -478,7 +478,7 @@ "interface.switch('refnx')\n", "model.interface = interface\n", "model_interface = model.interface()\n", - "model_data_no_magnetism_refnx = model.interface().reflectity_profile(\n", + "model_data_no_magnetism_refnx = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -488,7 +488,7 @@ "interface.switch('refl1d')\n", "model.interface = interface\n", "model_interface = model.interface()\n", - "model_data_no_magnetism_ref1d = model.interface().reflectity_profile(\n", + "model_data_no_magnetism_ref1d = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -518,7 +518,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.magnetism = True\n", - "model_data_magnetism = model.interface().reflectity_profile(\n", + "model_data_magnetism = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -529,7 +529,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.magnetism = False\n", - "model_data_no_magnetism = model.interface().reflectity_profile(\n", + "model_data_no_magnetism = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", diff --git a/docs/docs/tutorials/simulation/resolution_functions.ipynb b/docs/docs/tutorials/simulation/resolution_functions.ipynb index d46a76cb..cc7abe10 100644 --- a/docs/docs/tutorials/simulation/resolution_functions.ipynb +++ b/docs/docs/tutorials/simulation/resolution_functions.ipynb @@ -310,7 +310,7 @@ " num=1000,\n", " )\n", " model.resolution_function = resolution_function_dict[key]\n", - " model_data = model.interface().reflectity_profile(\n", + " model_data = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", " )\n", @@ -363,14 +363,14 @@ ")\n", "\n", "model.resolution_function = resolution_function_dict[key]\n", - "model_data = model.interface().reflectity_profile(\n", + "model_data = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", "plt.plot(model_coords, model_data, 'k-', label='Variable', linewidth=5)\n", "\n", "model.resolution_function = PercentageFwhm(1.0)\n", - "model_data = model.interface().reflectity_profile(\n", + "model_data = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -402,7 +402,7 @@ ")\n", "\n", "model.resolution_function = resolution_function_dict[key]\n", - "model_data = model.interface().reflectity_profile(\n", + "model_data = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -415,7 +415,7 @@ "data_points.append(reference_data) # R\n", "data_points.append(reference_variances) # sQz (variance of Qz)\n", "model.resolution_function = Pointwise(q_data_points=data_points)\n", - "model_data = model.interface().reflectity_profile(\n", + "model_data = model.interface().reflectivity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index f75e4657..1cd19cde 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -208,7 +208,8 @@ nav: - Elements: - Layers: - Layer: api-reference/elements/layer.md - - Layer Area Per Molecule: api-reference/elements/layer_area_per_molecule.md + - Layer Area Per Molecule: + api-reference/elements/layer_area_per_molecule.md - Materials: - Material: api-reference/elements/material.md - Material Density: api-reference/elements/material_density.md diff --git a/pixi.lock b/pixi.lock index 6b3a38bc..983bc0bd 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,8 +1,21 @@ version: 7 platforms: - name: linux-64 -- name: osx-arm64 + virtual-packages: + - __unix=0=0 + - __linux=4.18 + - __glibc=2.28 + - __archspec=0=x86_64 +- name: p1 + subdir: osx-arm64 + virtual-packages: + - __osx=14.0 + - __unix=0=0 + - __archspec=0=m1 - name: win-64 + virtual-packages: + - __win=10.0 + - __archspec=0=x86_64 environments: default: channels: @@ -189,8 +202,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -326,7 +339,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -500,8 +513,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -801,8 +814,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -1124,8 +1137,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl @@ -1259,7 +1272,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda @@ -1429,8 +1442,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl @@ -1724,8 +1737,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2047,8 +2060,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2184,7 +2197,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -2358,8 +2371,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2659,8 +2672,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: ./ + - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -3070,7 +3083,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -8297,12 +8310,13 @@ packages: purls: [] size: 388453 timestamp: 1764777142545 -- pypi: . +- pypi: ./ name: easyreflectometry requires_dist: - bumps - - easyscience @ git+https://github.com/easyscience/corelib@develop + - easyscience @ git+https://github.com/easyscience/corelib.git@develop - orsopy + - plotly - pooch - refl1d>=1.0.0 - refnx @@ -8344,7 +8358,7 @@ packages: - validate-pyproject[all] ; extra == 'dev' - versioningit ; extra == 'dev' requires_python: '>=3.11' -- pypi: git+https://github.com/easyscience/corelib?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 +- pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 name: easyscience version: 2.3.1+dev8 requires_dist: diff --git a/src/easyreflectometry/calculators/calculator_base.py b/src/easyreflectometry/calculators/calculator_base.py index e2a92804..06fa5f07 100644 --- a/src/easyreflectometry/calculators/calculator_base.py +++ b/src/easyreflectometry/calculators/calculator_base.py @@ -189,7 +189,7 @@ def remove_item_from_model(self, item_id: str, model_id: str) -> None: """ self._wrapper.remove_item(item_id, model_id) - def reflectity_profile(self, x_array: np.ndarray, model_id: str) -> np.ndarray: + def reflectivity_profile(self, x_array: np.ndarray, model_id: str) -> np.ndarray: """Determines the reflectivity profile for the given range and model. Parameters diff --git a/src/easyreflectometry/calculators/factory.py b/src/easyreflectometry/calculators/factory.py index c3e1479c..b1c1b170 100644 --- a/src/easyreflectometry/calculators/factory.py +++ b/src/easyreflectometry/calculators/factory.py @@ -40,6 +40,6 @@ def fit_func(self) -> Callable: def __fit_func(*args, **kwargs): """Fit func.""" - return self().reflectity_profile(*args, **kwargs) + return self().reflectivity_profile(*args, **kwargs) return __fit_func diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 83a3f6eb..3cb0ecb3 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -384,8 +384,8 @@ def mcmc_sample( — the population already exists in the saved state. :param progress_callback: Optional callback for progress updates during sampling. Forwarded to the core MultiFitter. - :return: Dictionary with keys ``'draws'``, ``'param_names'``, ``'state'``, - and ``'logp'``. + :return: Dictionary with keys ``'draws'``, ``'param_names'``, + ``'internal_bumps_object'``, and ``'logp'``. :raises RuntimeError: If the current minimizer is not a BUMPS instance. """ minimizer = self.easy_science_multi_fitter.minimizer @@ -494,19 +494,3 @@ def switch_minimizer(self, minimizer: AvailableMinimizers) -> None: Minimizer to be switched to. """ self.easy_science_multi_fitter.switch_minimizer(minimizer) - - -def _flatten_list(this_list: list) -> list: - """Flatten nested lists. - - Parameters - ---------- - this_list : list - List to be flattened. - - Returns - ------- - list - Flattened list. - """ - return np.array([item for sublist in this_list for item in sublist]) diff --git a/src/easyreflectometry/limits.py b/src/easyreflectometry/limits.py index 001bba64..8962ab9b 100644 --- a/src/easyreflectometry/limits.py +++ b/src/easyreflectometry/limits.py @@ -31,14 +31,19 @@ def apply_default_limits(parameter: Parameter, kind: str) -> None: def _apply_percentage_limits(parameter: Parameter) -> None: - """Set min to 50% and max to 200% of the current value, only if current bounds are inf.""" + """Set bounds to 50%-200% of the current value, only if current bounds are inf. + + For negative values 0.5*value > 2*value, so the candidates are ordered + to keep min <= value <= max. + """ value = parameter.value if value == 0.0: return + low, high = sorted((0.5 * value, 2.0 * value)) if np.isinf(parameter.min): - parameter.min = 0.5 * value + parameter.min = low if np.isinf(parameter.max): - parameter.max = 2.0 * value + parameter.max = high def _apply_fixed_limits(parameter: Parameter, low: float, high: float) -> None: diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index da1396d0..5aa32833 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -148,12 +148,12 @@ def background(self, value: float) -> None: # ----- assembly management ----- - def add_assemblies(self, *assemblies: list[BaseAssembly]) -> None: + def add_assemblies(self, *assemblies: BaseAssembly) -> None: """Add assemblies to the model sample. Parameters ---------- - *assemblies : list[BaseAssembly] + *assemblies : BaseAssembly Assemblies to add to model sample. """ if not assemblies: diff --git a/src/easyreflectometry/model/resolution_functions.py b/src/easyreflectometry/model/resolution_functions.py index fe5d2254..c723bf14 100644 --- a/src/easyreflectometry/model/resolution_functions.py +++ b/src/easyreflectometry/model/resolution_functions.py @@ -10,6 +10,7 @@ from __future__ import annotations +from abc import ABC from abc import abstractmethod from typing import List from typing import Optional @@ -20,7 +21,7 @@ DEFAULT_RESOLUTION_FWHM_PERCENTAGE = 5.0 -class ResolutionFunction: +class ResolutionFunction(ABC): @abstractmethod def smearing(self, q: Union[np.array, float]) -> np.array: ... diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 5ae272a6..fe4af1bf 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -346,29 +346,30 @@ def path_json(self): """Path json.""" return self.path / 'project.json' + def _get_or_add_material_index(self, name: str, sld: float, isld: float) -> int: + """Return the index of the named material, adding it to the project + materials first if not present. This mutates ``self._materials``.""" + names = [material.name for material in self._materials] + if name not in names: + self._materials.add_material(Material(name=name, sld=sld, isld=isld)) + names.append(name) + return names.index(name) + def get_index_air(self) -> int: - """Get index air.""" - if 'Air' not in [material.name for material in self._materials]: - self._materials.add_material(Material(name='Air', sld=0.0, isld=0.0)) - return [material.name for material in self._materials].index('Air') + """Index of the Air material, adding it to the project if missing.""" + return self._get_or_add_material_index('Air', sld=0.0, isld=0.0) def get_index_si(self) -> int: - """Get index si.""" - if 'Si' not in [material.name for material in self._materials]: - self._materials.add_material(Material(name='Si', sld=2.07, isld=0.0)) - return [material.name for material in self._materials].index('Si') + """Index of the Si material, adding it to the project if missing.""" + return self._get_or_add_material_index('Si', sld=2.07, isld=0.0) def get_index_sio2(self) -> int: - """Get index sio2.""" - if 'SiO2' not in [material.name for material in self._materials]: - self._materials.add_material(Material(name='SiO2', sld=3.47, isld=0.0)) - return [material.name for material in self._materials].index('SiO2') + """Index of the SiO2 material, adding it to the project if missing.""" + return self._get_or_add_material_index('SiO2', sld=3.47, isld=0.0) def get_index_d2o(self) -> int: - """Get index d2o.""" - if 'D2O' not in [material.name for material in self._materials]: - self._materials.add_material(Material(name='D2O', sld=6.36, isld=0.0)) - return [material.name for material in self._materials].index('D2O') + """Index of the D2O material, adding it to the project if missing.""" + return self._get_or_add_material_index('D2O', sld=6.36, isld=0.0) def load_orso_file(self, path: Union[Path, str]) -> None: """Load an ORSO file and optionally create a model and a data from it.""" @@ -386,7 +387,6 @@ def load_orso_file(self, path: Union[Path, str]) -> None: self._experiments[0].name = 'Experiment from ORSO' self._experiments[0].model = self.models[0] self._with_experiments = True - pass def set_sample_from_orso(self, sample: Sample) -> None: """Replace the current project model collection with a single model built from an ORSO-parsed sample. @@ -665,7 +665,7 @@ def model_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.arr if q_range is None: q_range = np.linspace(self.q_min, self.q_max, self.q_resolution) self.models[index].interface = self._calculator - reflectivity = self.models[index].interface().reflectity_profile(q_range, self._models[index].unique_name) + reflectivity = self.models[index].interface().reflectivity_profile(q_range, self._models[index].unique_name) return DataSet1D( name=f'Reflectivity for Model {index}', x=q_range, @@ -868,10 +868,10 @@ def as_dict(self, include_materials_not_in_model=False): self._as_dict_add_materials_not_in_model_dict(project_dict) if self._with_experiments: self._as_dict_add_experiments(project_dict) - if self.fitter is not None: - project_dict['fitter_minimizer'] = self.fitter.easy_science_multi_fitter.minimizer.name - elif self._minimizer_selection is not None: - project_dict['fitter_minimizer'] = self._minimizer_selection.name + # Read the minimizer without touching the lazy `fitter` property: + # serialization must not construct a MultiFitter as a side effect. + if self.minimizer is not None: + project_dict['fitter_minimizer'] = self.minimizer.name if self._calculator is not None: project_dict['calculator'] = self._calculator.current_interface_name if self._colors is not None: diff --git a/src/easyreflectometry/sample/elements/materials/material_mixture.py b/src/easyreflectometry/sample/elements/materials/material_mixture.py index 1ab76ddc..b5b88e27 100644 --- a/src/easyreflectometry/sample/elements/materials/material_mixture.py +++ b/src/easyreflectometry/sample/elements/materials/material_mixture.py @@ -152,17 +152,16 @@ def fraction(self, value: float) -> None: # ----- derived sld / isld parameters (shared shape with Material) ----- # # These are *derived* via the constraints set up in `_materials_constraints` - # (not constructor arguments) so we expose them as floats to match the - # legacy MaterialMixture API. The underlying Parameter objects remain - # available as `self._sld` / `self._isld`. + # (not constructor arguments), so unlike Material there are no setters: + # their values follow the child materials and the fraction. @property - def sld(self) -> float: - return self._sld.value + def sld(self) -> Parameter: + return self._sld @property - def isld(self) -> float: - return self._isld.value + def isld(self) -> Parameter: + return self._isld # ----- calculator binding ----- @@ -171,8 +170,8 @@ def _get_linkable_attributes(self): Override of the inherited `BaseCore._get_linkable_attributes`, which walks `get_all_variables()` and would otherwise expose the **child** - materials' sld/isld (because our own `sld` / `isld` are floats, not - Parameters). The calculator's `InterfaceFactoryTemplate.generate_bindings` + materials' sld/isld alongside the mixed ones. The calculator's + `InterfaceFactoryTemplate.generate_bindings` matches by parameter `name`; without this override it binds to `material_a.sld` and reflectivity is computed off the wrong SLD. """ diff --git a/src/easyreflectometry/special/calculations.py b/src/easyreflectometry/special/calculations.py index 07844d3c..9c6e43c2 100644 --- a/src/easyreflectometry/special/calculations.py +++ b/src/easyreflectometry/special/calculations.py @@ -44,11 +44,13 @@ def neutron_scattering_length(formula: str) -> complex: scattering_length = 0 + 0j for key, value in formula_as_dict.items(): scattering_length += pt.elements.symbol(key).neutron.b_c * value + # b_c_i is the imaginary (absorption) part of the bound coherent + # scattering length, not the incoherent scattering length. if pt.elements.symbol(key).neutron.b_c_i: - inc = pt.elements.symbol(key).neutron.b_c_i + imag = pt.elements.symbol(key).neutron.b_c_i else: - inc = 0 - scattering_length += inc * 1j * value + imag = 0 + scattering_length += imag * 1j * value return scattering_length * 1e-5 @@ -63,7 +65,7 @@ def molecular_weight(formula: str) -> float: Returns ------- float - Molecular weight of the material in kilograms. + Molecular weight of the material in u (g/mol). """ formula_as_dict = parse_formula(formula) mw = 0 diff --git a/tests/calculators/refl1d/test_refl1d_calculator.py b/tests/calculators/refl1d/test_refl1d_calculator.py index 50de2db4..a27d1f7a 100644 --- a/tests/calculators/refl1d/test_refl1d_calculator.py +++ b/tests/calculators/refl1d/test_refl1d_calculator.py @@ -27,7 +27,7 @@ def test_init(self): assert_equal(p._model_link['background'], 'bkg') assert_equal(p.name, 'refl1d') - def test_reflectity_profile(self): + def test_reflectivity_profile(self): p = Refl1d() p._wrapper.create_material('Material1') p._wrapper.update_material('Material1', rho=0.000, irho=0.000) @@ -63,7 +63,7 @@ def test_reflectity_profile(self): 1.3093e-07, 1.0520e-07, ] - assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected, decimal=4) + assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected, decimal=4) def test_calculate2(self): p = Refl1d() @@ -95,7 +95,7 @@ def test_calculate2(self): p._wrapper.add_item('Item3', 'MyModel') p._wrapper.update_item('Item2', repeat=10) q = np.linspace(0.001, 0.3, 10) - actual = p.reflectity_profile(q, 'MyModel') + actual = p.reflectivity_profile(q, 'MyModel') expected = [ 9.9949e-01, 8.7414e-03, @@ -140,7 +140,7 @@ def test_calculate_magnetic(self): p._wrapper.add_item('Item2', 'MyModel') p._wrapper.add_item('Item3', 'MyModel') q = np.linspace(0.001, 0.3, 10) - actual = p.reflectity_profile(q, 'MyModel') + actual = p.reflectivity_profile(q, 'MyModel') expected = [ 9.99491251e-01, 1.08413641e-02, diff --git a/tests/calculators/refnx/test_refnx_calculator.py b/tests/calculators/refnx/test_refnx_calculator.py index baeb9296..e4efae68 100644 --- a/tests/calculators/refnx/test_refnx_calculator.py +++ b/tests/calculators/refnx/test_refnx_calculator.py @@ -27,7 +27,7 @@ def test_init(self): assert_equal(p._model_link['background'], 'bkg') assert_equal(p.name, 'refnx') - def test_reflectity_profile(self): + def test_reflectivity_profile(self): p = Refnx() p._wrapper.create_material('Material1') p._wrapper.update_material('Material1', real=0.000, imag=0.000) @@ -62,7 +62,7 @@ def test_reflectity_profile(self): 1.26726993e-07, 1.01842852e-07, ] - assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected) + assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected) def test_calculate2(self): p = Refnx() @@ -105,7 +105,7 @@ def test_calculate2(self): 3.4981523e-07, 2.5424356e-07, ] - assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected) + assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected) def test_sld_profile(self): p = Refnx() diff --git a/tests/model/test_model.py b/tests/model/test_model.py index b11149c1..0c83d5dc 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -427,8 +427,8 @@ def test_dict_round_trip(interface): if interface is not None: assert model.interface().name == model_from_dict.interface().name assert_almost_equal( - model.interface().reflectity_profile([0.3], model.unique_name), - model_from_dict.interface().reflectity_profile([0.3], model_from_dict.unique_name), + model.interface().reflectivity_profile([0.3], model.unique_name), + model_from_dict.interface().reflectivity_profile([0.3], model_from_dict.unique_name), ) diff --git a/tests/model/test_resolution_functions.py b/tests/model/test_resolution_functions.py index b8a4ea18..1391949b 100644 --- a/tests/model/test_resolution_functions.py +++ b/tests/model/test_resolution_functions.py @@ -38,7 +38,7 @@ def test_as_dict(self): resolution_function = PercentageFwhm(1.0) # Then Expect - resolution_function.as_dict() == {'smearing': 'PercentageFwhm', 'constant': 1.0} + assert resolution_function.as_dict() == {'smearing': 'PercentageFwhm', 'constant': 1.0} def test_dict_round_trip(self): # When @@ -67,7 +67,7 @@ def test_as_dict(self): resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) # Then Expect - resolution_function.as_dict() == { + assert resolution_function.as_dict() == { 'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10], @@ -117,7 +117,12 @@ def test_as_dict(self): resolution_function = Pointwise(q_data_points=self.data_points) # Then Expect - assert resolution_function.as_dict(), {'smearing': 'Pointwise', 'q_data_points': [0, 10]} + assert resolution_function.as_dict() == { + 'smearing': 'Pointwise', + 'q_data_points': self.data_points[0], + 'R_data_points': self.data_points[1], + 'sQz_data_points': self.data_points[2], + } def test_dict_round_trip(self): # When diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index 0d466be7..7fe04009 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -27,8 +27,8 @@ def test_default(self): assert p.roughness.value == 3.3 assert str(p.roughness.unit) == 'Å' assert p.roughness.fixed is True - assert_almost_equal(p.material.sld, 2.268770124481328) - assert_almost_equal(p.material.isld, 0) + assert_almost_equal(p.material.sld.value, 2.268770124481328) + assert_almost_equal(p.material.isld.value, 0) assert p.material.name == 'C10H18NO8P in D2O' assert p.solvent.sld.value == 6.36 assert p.solvent.isld.value == 0 @@ -69,7 +69,7 @@ def test_from_pars_constraint(self): ) assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld, 0.31494833333333333) + assert_almost_equal(p.material.sld.value, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 @@ -77,10 +77,10 @@ def test_from_pars_constraint(self): assert p.solvent_fraction.value == 0.5 p.area_per_molecule = 30 assert p.area_per_molecule.value == 30 - assert_almost_equal(p.material.sld, 0.7119138888888887) + assert_almost_equal(p.material.sld.value, 0.7119138888888887) p.thickness.value = 10 assert p.thickness.value == 10 - assert_almost_equal(p.material.sld, 0.9103966666666665) + assert_almost_equal(p.material.sld.value, 0.9103966666666665) @unittest.skip('Instantiation of LayerAreaPerMolecule fails, despite working everywhere else.') def test_solvent_change(self): @@ -97,7 +97,7 @@ def test_solvent_change(self): assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 print(p.material) - assert_almost_equal(p.material.sld, 0.31494833333333333) + assert_almost_equal(p.material.sld.value, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 @@ -107,7 +107,7 @@ def test_solvent_change(self): p.solvent = d2o assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld, 3.762948333333333) + assert_almost_equal(p.material.sld.value, 3.762948333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == 6.335 @@ -127,7 +127,7 @@ def test_molecular_formula_change(self): ) assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld, 0.31494833333333333) + assert_almost_equal(p.material.sld.value, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 @@ -138,7 +138,7 @@ def test_molecular_formula_change(self): p.molecular_formula = 'C8O10D12P' assert p.molecular_formula == 'C8O10D12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld, 1.3558483333333333) + assert_almost_equal(p.material.sld.value, 1.3558483333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 diff --git a/tests/sample/elements/materials/test_material_mixture.py b/tests/sample/elements/materials/test_material_mixture.py index 3c2a3f65..d3912b7d 100644 --- a/tests/sample/elements/materials/test_material_mixture.py +++ b/tests/sample/elements/materials/test_material_mixture.py @@ -15,8 +15,8 @@ def test_default(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.186) - assert_almost_equal(material_mixture.isld, 0) + assert_almost_equal(material_mixture.sld.value, 4.186) + assert_almost_equal(material_mixture.isld.value, 0) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -24,12 +24,12 @@ def test_default_constraint(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.186) - assert_almost_equal(material_mixture.isld, 0) + assert_almost_equal(material_mixture.sld.value, 4.186) + assert_almost_equal(material_mixture.isld.value, 0) material_mixture.material_a.sld.value = 0 material_mixture.material_b.isld.value = -1 - assert_almost_equal(material_mixture.sld, 2.093) - assert_almost_equal(material_mixture.isld, -0.5) + assert_almost_equal(material_mixture.sld.value, 2.093) + assert_almost_equal(material_mixture.isld.value, -0.5) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -38,59 +38,59 @@ def test_fraction_constraint(self): q = Material(6.908, -0.278, 'Boron') material_mixture = MaterialMixture(p, q, 0.2) assert material_mixture.fraction.value == 0.2 - assert_almost_equal(material_mixture.sld, 4.7304) - assert_almost_equal(material_mixture.isld, -0.0556) + assert_almost_equal(material_mixture.sld.value, 4.7304) + assert_almost_equal(material_mixture.isld.value, -0.0556) material_mixture._fraction.value = 0.5 assert material_mixture.fraction.value == 0.5 - assert_almost_equal(material_mixture.sld, 5.54700) - assert_almost_equal(material_mixture.isld, -0.1390) + assert_almost_equal(material_mixture.sld.value, 5.54700) + assert_almost_equal(material_mixture.isld.value, -0.1390) def test_material_a_change(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.186) - assert_almost_equal(material_mixture.isld, 0) + assert_almost_equal(material_mixture.sld.value, 4.186) + assert_almost_equal(material_mixture.isld.value, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_a = q assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 5.54700) - assert_almost_equal(material_mixture.isld, -0.1390) + assert_almost_equal(material_mixture.sld.value, 5.54700) + assert_almost_equal(material_mixture.isld.value, -0.1390) def test_material_b_change(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.186) - assert_almost_equal(material_mixture.isld, 0) + assert_almost_equal(material_mixture.sld.value, 4.186) + assert_almost_equal(material_mixture.isld.value, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 5.54700) - assert_almost_equal(material_mixture.isld, -0.1390) + assert_almost_equal(material_mixture.sld.value, 5.54700) + assert_almost_equal(material_mixture.isld.value, -0.1390) def test_material_b_change_double(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.186) - assert_almost_equal(material_mixture.isld, 0) + assert_almost_equal(material_mixture.sld.value, 4.186) + assert_almost_equal(material_mixture.isld.value, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q assert material_mixture.name == 'EasyMaterial/Boron' assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 5.54700) - assert_almost_equal(material_mixture.isld, -0.1390) + assert_almost_equal(material_mixture.sld.value, 5.54700) + assert_almost_equal(material_mixture.isld.value, -0.1390) r = Material(0.00, 0.00, 'ACMW') material_mixture.material_b = r assert material_mixture.name == 'EasyMaterial/ACMW' assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 2.0930) - assert_almost_equal(material_mixture.isld, 0.0000) + assert_almost_equal(material_mixture.sld.value, 2.0930) + assert_almost_equal(material_mixture.isld.value, 0.0000) def test_from_pars(self): p = Material() @@ -98,8 +98,8 @@ def test_from_pars(self): material_mixture = MaterialMixture(p, q, 0.2) assert material_mixture.fraction.value == 0.2 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld, 4.7304) - assert_almost_equal(material_mixture.isld, -0.0556) + assert_almost_equal(material_mixture.sld.value, 4.7304) + assert_almost_equal(material_mixture.isld.value, -0.0556) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -158,7 +158,7 @@ def test_calculator_binding_uses_mixed_sld(self) -> None: mixture = MaterialMixture(material_a, material_b, fraction=0.25, interface=interface) # 2 * 0.75 + 6 * 0.25 = 1.5 + 1.5 = 3.0 - assert_almost_equal(mixture.sld, 3.0) + assert_almost_equal(mixture.sld.value, 3.0) wrapper_material = interface()._wrapper.storage['material'][mixture.unique_name] assert_almost_equal(wrapper_material.real.value, 3.0) assert_almost_equal(wrapper_material.imag.value, 0.0) @@ -173,8 +173,8 @@ def test_mutation_propagates_after_round_trip(self) -> None: global_object.map._clear() q = MaterialMixture.from_dict(p_dict) - assert_almost_equal(q.sld, 3.0) + assert_almost_equal(q.sld.value, 3.0) q.fraction = 0.8 # 2 * 0.2 + 6 * 0.8 = 0.4 + 4.8 = 5.2 - assert_almost_equal(q.sld, 5.2) + assert_almost_equal(q.sld.value, 5.2) diff --git a/tests/test_project.py b/tests/test_project.py index ec85b3f2..b1ae72eb 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -476,7 +476,7 @@ def test_as_dict_minimizer(self): project = Project() project._fitter = MagicMock() project._fitter.easy_science_multi_fitter = MagicMock() - project._fitter.easy_science_multi_fitter.minimizer = AvailableMinimizers.LMFit + project._fitter.easy_science_multi_fitter.minimizer.enum = AvailableMinimizers.LMFit # Then project_dict = project.as_dict() diff --git a/tests/test_topmost_nesting.py b/tests/test_topmost_nesting.py index 622991b2..1003efe5 100644 --- a/tests/test_topmost_nesting.py +++ b/tests/test_topmost_nesting.py @@ -47,8 +47,8 @@ def test_copy(): assert model._resolution_function.smearing(5.5) == model_copy._resolution_function.smearing(5.5) assert model.interface().name == model_copy.interface().name assert_almost_equal( - model.interface().reflectity_profile([0.3], model.unique_name), - model_copy.interface().reflectity_profile([0.3], model_copy.unique_name), + model.interface().reflectivity_profile([0.3], model.unique_name), + model_copy.interface().reflectivity_profile([0.3], model_copy.unique_name), ) assert model.unique_name != model_copy.unique_name assert model.name == model_copy.name From 90fed4f37b9366f5f9cee1c965a3b0cf97012836 Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Mon, 27 Jul 2026 13:16:46 +0200 Subject: [PATCH 18/22] fixes for summary printout #375 (#385) --- src/easyreflectometry/fitting.py | 18 ++++++++ .../summary/html_templates.py | 2 +- src/easyreflectometry/summary/summary.py | 28 +++++------ tests/summary/test_summary.py | 46 +++++++++++++++++++ tests/test_fitting.py | 40 ++++++++++++++++ 5 files changed, 120 insertions(+), 14 deletions(-) diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 3cb0ecb3..4cd24004 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -355,6 +355,24 @@ def fit_single_data_set_1d(self, data: DataSet1D, objective: str | None = None) ] return result + def record_fit_results(self, results: list[FitResults] | None) -> None: + """Record fit results produced outside this fitter instance. + + The application runs threaded fits directly on the lower-level + ``easy_science_multi_fitter`` (for progress reporting and cancellation) + rather than through :meth:`fit`. As a result, the high-level + ``_fit_results`` used by :attr:`chi2`, :attr:`reduced_chi`, and the + HTML summary's goodness-of-fit are never populated. Call this after such + a fit so those consumers reflect the latest results. Pass ``None`` to + clear. + + :param results: The list of ``FitResults`` from the completed fit, or + ``None`` to reset. + """ + self._fit_results = results + if not results: + self._classical_fit_metrics = None + def mcmc_sample( self, data: sc.DataGroup, diff --git a/src/easyreflectometry/summary/html_templates.py b/src/easyreflectometry/summary/html_templates.py index 9df780aa..fe520e2b 100644 --- a/src/easyreflectometry/summary/html_templates.py +++ b/src/easyreflectometry/summary/html_templates.py @@ -141,7 +141,7 @@ No. of constraints - num_constriants + num_constraints """ diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index f40f23ad..d8df7bd2 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -309,26 +309,28 @@ def _refinement_section(self) -> str: html_refinement = html_refinement.replace('num_total_params', f'{num_params}') html_refinement = html_refinement.replace('num_free_params', f'{num_free_params}') html_refinement = html_refinement.replace('num_fixed_params', f'{num_fixed_params}') - html_refinement = html_refinement.replace('num_constriants', f'{num_constraints}') + html_refinement = html_refinement.replace('num_constraints', f'{num_constraints}') return html_refinement def _compute_goodness_of_fit(self) -> str: - """Return reduced chi² as a formatted string, or 'N/A' if no fit has been run.""" - last_fit_results = getattr(self._project, '_last_fit_results', None) - if not last_fit_results: + """Return reduced chi² as a formatted string, or 'N/A' if no fit has been run. + + The value is read from the project's fitter, which computes the reduced + chi-square directly from the raw chi-square and the global degrees of + freedom across every fitted dataset. Deriving it this way keeps the + summary independent of the per-minimizer ``reduced_chi`` / ``reduced_chi2`` + attribute naming used by the underlying ``FitResults`` objects. + """ + fitter = self._project.fitter + if fitter is None: return 'N/A' try: - if len(last_fit_results) == 1: - gof = float(last_fit_results[0].reduced_chi2) - else: - total_chi2 = sum(float(r.chi2) for r in last_fit_results) - total_points = sum(len(r.x) for r in last_fit_results) - n_pars = last_fit_results[0].n_pars - dof = total_points - n_pars - gof = total_chi2 / dof if dof > 0 else 0.0 - return f'{gof:.4g}' + gof = fitter.reduced_chi except (AttributeError, TypeError, ValueError, ZeroDivisionError): return 'N/A' + if gof is None: + return 'N/A' + return f'{gof:.4g}' def _figures_section(self, interactive: bool = True) -> str: """Figures section. diff --git a/tests/summary/test_summary.py b/tests/summary/test_summary.py index 5f135fb0..271de2c4 100644 --- a/tests/summary/test_summary.py +++ b/tests/summary/test_summary.py @@ -4,6 +4,7 @@ import os from unittest.mock import MagicMock +import numpy as np import pytest from easyscience import global_object @@ -167,6 +168,51 @@ def test_refinement_section(self, project: Project) -> None: assert 'No. of free parameters:' in html assert '0' in html assert 'No. of constraints' in html + # The (previously misspelt) constraints token must be fully substituted. + assert 'num_constriants' not in html + assert 'num_constraints' not in html + + @staticmethod + def _populate_fit_results(project: Project, chi2: float, n_points: int, n_pars: int) -> None: + """Emulate a completed fit by storing results on the project's fitter.""" + fit_result = MagicMock() + fit_result.chi2 = chi2 + fit_result.x = np.arange(n_points) + fit_result.n_pars = n_pars + project.fitter._fit_results = [fit_result] + + def test_compute_goodness_of_fit_na_before_fit(self, project: Project) -> None: + # When + summary = Summary(project) + + # Then Expect: no fit has been run, so goodness-of-fit is unavailable. + assert summary._compute_goodness_of_fit() == 'N/A' + + def test_compute_goodness_of_fit_after_fit(self, project: Project) -> None: + # When: reduced chi² = 20 / (14 - 4) = 2.0 + summary = Summary(project) + self._populate_fit_results(project, chi2=20.0, n_points=14, n_pars=4) + + # Then + gof = summary._compute_goodness_of_fit() + + # Expect + assert gof != 'N/A' + assert float(gof) == pytest.approx(2.0) + + def test_refinement_section_shows_goodness_of_fit(self, project: Project) -> None: + # When + summary = Summary(project) + self._populate_fit_results(project, chi2=20.0, n_points=14, n_pars=4) + gof = summary._compute_goodness_of_fit() + + # Then + html = summary._refinement_section() + + # Expect: the template token is replaced with the actual value, not 'N/A'. + assert gof != 'N/A' + assert gof in html + assert 'goodness_of_fit' not in html def test_save_sld_plot(self, project: Project, tmp_path) -> None: # When diff --git a/tests/test_fitting.py b/tests/test_fitting.py index e4f938c8..896de593 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -287,6 +287,46 @@ def test_reduced_chi_uses_global_dof_across_fit_results(): assert fitter.reduced_chi == pytest.approx(expected) +def test_record_fit_results_populates_reduced_chi(): + """Results computed outside the fitter can be recorded so reduced_chi works. + + Mirrors the app path where the threaded fit runs on the low-level + easy_science_multi_fitter and the high-level results must be recorded + explicitly (otherwise the HTML summary goodness-of-fit shows 'N/A'). + """ + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + assert fitter.reduced_chi is None + + fit_result = MagicMock() + fit_result.chi2 = 20.0 + fit_result.x = np.arange(14) + fit_result.n_pars = 4 + + fitter.record_fit_results([fit_result]) + + assert fitter.reduced_chi == pytest.approx(20.0 / (14 - 4)) + + +def test_record_fit_results_none_clears_state(): + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + + fit_result = MagicMock() + fit_result.chi2 = 20.0 + fit_result.x = np.arange(14) + fit_result.n_pars = 4 + fitter.record_fit_results([fit_result]) + + fitter.record_fit_results(None) + + assert fitter.reduced_chi is None + assert fitter.chi2 is None + + def test_fit_single_data_set_1d_all_zero_variance_raises(): """Legacy mask mode raises when all points have zero variance.""" model = Model() From 01c07d5c14f580b20a540115b23cfad4534b1e9e Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Thu, 30 Jul 2026 20:00:48 +0200 Subject: [PATCH 19/22] Core fixes (#383) * moved to Sampler class from Core * reparent branch * fixed issue #367 (#382) * fixed issue #367 * disable automatic parallelization for windows * Changes after code review * added test * arviz fix * try to fix prettier issues * updated notebook * linting * fixing #370 (#388) * reparent to develop * Core fixes pointwise (#387) * fixed pointwise treatment on file load * more tests --- .github/workflows/pypi-test.yml | 4 +- .github/workflows/test.yml | 4 +- CHANGELOG.md | 50 ++ .../advancedfitting/bayesian_bumps.ipynb | 557 ++++++++++-------- docs/docs/tutorials/simulation/bilayer.ipynb | 10 +- .../docs/tutorials/simulation/magnetism.ipynb | 16 +- .../simulation/resolution_functions.ipynb | 10 +- pixi.lock | 67 +-- pixi.toml | 10 +- src/easyreflectometry/analysis/bayesian.py | 5 +- .../calculators/calculator_base.py | 2 +- src/easyreflectometry/calculators/factory.py | 2 +- .../calculators/refl1d/wrapper.py | 7 +- .../calculators/refnx/wrapper.py | 10 +- src/easyreflectometry/fitting.py | 101 +++- src/easyreflectometry/limits.py | 11 +- src/easyreflectometry/model/model.py | 4 +- .../model/resolution_functions.py | 45 +- src/easyreflectometry/project.py | 54 +- .../elements/materials/material_mixture.py | 17 +- src/easyreflectometry/special/calculations.py | 10 +- .../summary/html_templates.py | 2 +- src/easyreflectometry/summary/summary.py | 28 +- .../refl1d/test_refl1d_calculator.py | 8 +- .../refnx/test_refnx_calculator.py | 6 +- tests/calculators/refnx/test_refnx_wrapper.py | 2 +- .../test_resolution_conventions.py | 207 +++++++ .../test_cross_engine_resolution.py | 187 ++++++ tests/model/test_model.py | 17 +- tests/model/test_resolution_functions.py | 45 +- .../layers/test_layer_area_per_molecule.py | 18 +- .../materials/test_material_mixture.py | 58 +- tests/summary/test_summary.py | 48 +- tests/test_fitting.py | 420 +++++++++---- tests/test_project.py | 57 +- tests/test_topmost_nesting.py | 4 +- tests/unit/test_fitting_mcmc.py | 220 +++++++ tests/unit/test_material_and_calculations.py | 95 +++ tests/unit/test_project_core.py | 143 +++++ tests/unit/test_summary_goodness_of_fit.py | 86 +++ 40 files changed, 1957 insertions(+), 690 deletions(-) create mode 100644 tests/calculators/test_resolution_conventions.py create mode 100644 tests/integration/test_cross_engine_resolution.py create mode 100644 tests/unit/test_fitting_mcmc.py create mode 100644 tests/unit/test_material_and_calculations.py create mode 100644 tests/unit/test_project_core.py create mode 100644 tests/unit/test_summary_goodness_of_fit.py diff --git a/.github/workflows/pypi-test.yml b/.github/workflows/pypi-test.yml index 2f4f58ac..8bcb4b5e 100644 --- a/.github/workflows/pypi-test.yml +++ b/.github/workflows/pypi-test.yml @@ -71,7 +71,9 @@ jobs: - name: Run integration tests to verify the installation working-directory: easyreflectometry - run: pixi run python -m pytest ../tests/integration/ --color=yes -n auto + # No -n auto: concurrent xdist workers race on arviz's daily-warning + # stamp file when they import easyreflectometry. See pixi.toml. + run: pixi run python -m pytest ../tests/integration/ --color=yes # Job 2: Build and publish dashboard (reusable workflow) run-reusable-workflows: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6bf99c45..530c154f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -293,7 +293,9 @@ jobs: cd easyreflectometry_py$py_ver echo "Running tests" - pixi run python -m pytest ../tests/integration/ --color=yes -n auto -v ${{ needs.env-prepare.outputs.pytest-marks }} + # No -n auto: concurrent xdist workers race on arviz's daily-warning + # stamp file when they import easyreflectometry. See pixi.toml. + pixi run python -m pytest ../tests/integration/ --color=yes -v ${{ needs.env-prepare.outputs.pytest-marks }} echo "Exiting pixi project directory" cd .. diff --git a/CHANGELOG.md b/CHANGELOG.md index 2537591f..55aafcae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Unreleased +Restored the measured per-point resolution on data load (issue #368). + +- Loading data through `Project` (`load_new_experiment`, + `load_experiment_for_model_at_index`, + `load_all_experiments_from_file`) again sets a `Pointwise` resolution + function when the file carries per-point q-resolution (an sQz column + in `.ort` files, or a 4th column in text files). Since PR #293 the + loaders discarded this data and always applied a flat + `PercentageFwhm(5.0)` — a temporary workaround that never got + reverted. Fits of such data were smeared with 5% FWHM regardless of + what the instrument delivered and should be re-run. +- Files without q-resolution data keep the 5% FWHM default. The pre-#293 + fallback that built a `LinearSpline` from the _reflectivity_ error + (`sqrt(ye)`) was not restored: a reflectivity uncertainty is not a + q-width, and that branch produced effectively zero smearing. +- Known limitation (pre-existing): the resolution function lives on the + model, so when several experiments share one model the last-loaded + dataset's resolution wins. + +Fixed inconsistent interpretation of vector resolution functions between +the refnx and refl1d engines (issue #367). + +- **Reflectivity results change for two engine / resolution + combinations.** `LinearSpline` on refl1d previously **over-smeared by + a factor of 2.355** (its FWHM widths were passed to refl1d's + `probe.dQ`, which expects sigma). `Pointwise` on refnx previously + **under-smeared by the same factor** (its sigma widths were passed to + refnx's `x_err`, which expects FWHM). Both are now correct. Fits and + simulations that used either combination will produce different — + previously wrong — results and should be re-run. `PercentageFwhm` on + either engine, `LinearSpline` on refnx, and `Pointwise` on refl1d are + numerically unchanged. +- `ResolutionFunction.smearing()` now returns **sigma** (the Gaussian + standard deviation) for every subclass; each engine wrapper converts + to its backend's convention. This is a behavioural change to a public + method. Most visibly, `PercentageFwhm.smearing(q)` used to return the + _percentage_ itself (e.g. `5.0`) and now returns an absolute sigma + (e.g. `0.00212` at `q=0.1`); `LinearSpline.smearing(q)` returns its + `fwhm_values` divided by `2*sqrt(2*ln2)`. Callers relying on the old + values need to convert. The new `SIGMA_TO_FWHM` constant is exported + from `easyreflectometry.model.resolution_functions`. +- Constructors are **unchanged**: `PercentageFwhm(5)` still means 5% + FWHM and `LinearSpline(q, fwhm_values)` still takes FWHM. Only the + `smearing()` output convention moved, so existing model-building code + needs no edits. +- `PercentageFwhm.smearing(q)` given a scalar `q` now returns a 0-d + numpy scalar rather than a shape-`(1,)` array, matching + `LinearSpline`. `smearing(0.1)[0]` therefore raises `IndexError` where + it previously returned a value. + Migrated sample / model classes off the deprecated `easyscience.ObjBase` and `easyscience.CollectionBase` pipeline. diff --git a/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb b/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb index 1c7e1bf6..dcaaa025 100644 --- a/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb +++ b/docs/docs/tutorials/advancedfitting/bayesian_bumps.ipynb @@ -16,11 +16,18 @@ "- Classical optimisation first (good starting point for Bayesian sampling).\n", "- High-level DREAM MCMC sampling via\n", " ``MultiFitter.mcmc_sample()`` and ``PosteriorResults``.\n", + "- Checking convergence with the Gelman-Rubin R-hat diagnostic, then\n", + " **extending an under-converged chain** with ``fitter.sampler.extend()`` and\n", + " comparing the posterior before and after.\n", "- Posterior inspection: summary table, marginal distributions, corner plot,\n", - " trace plot, credible intervals, Gelman-Rubin R-hat.\n", + " trace plot, credible intervals.\n", "- Posterior-predictive checks: reflectivity and SLD profile with 95 %\n", " credible bands.\n", "\n", + "The sampling run below is deliberately started short so that the diagnostic\n", + "flags it as not converged — this gives us something real to fix when we extend\n", + "the chain, rather than a cosmetic demonstration.\n", + "\n", "All posterior plots are rendered as **interactive Plotly figures**, the\n", "same ones shown by the EasyReflectometryApp Bayesian Posterior tab.\n", "\n", @@ -30,25 +37,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "61aa83ac", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:06.282846Z", - "iopub.status.busy": "2026-05-29T06:29:06.282846Z", - "iopub.status.idle": "2026-05-29T06:29:09.516170Z", - "shell.execute_reply": "2026-05-29T06:29:09.516170Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All libraries imported successfully.\n" - ] - } - ], + "metadata": {}, + "outputs": [], "source": [ "import warnings\n", "\n", @@ -79,35 +71,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "14986b98", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:09.517778Z", - "iopub.status.busy": "2026-05-29T06:29:09.517778Z", - "iopub.status.idle": "2026-05-29T06:29:09.958508Z", - "shell.execute_reply": "2026-05-29T06:29:09.958508Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data loaded with keys: ['data', 'coords', 'attrs']\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "metadata": {}, + "outputs": [], "source": [ "# ---- Load experimental data -------------------------------------------------\n", "# Fetch the .ort test data from the easyscience/reflectometry data repository.\n", @@ -134,29 +101,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "cd56a6eb", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:09.960548Z", - "iopub.status.busy": "2026-05-29T06:29:09.960548Z", - "iopub.status.idle": "2026-05-29T06:29:09.973595Z", - "shell.execute_reply": "2026-05-29T06:29:09.973595Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model created with the following free parameters:\n", - " background: value=1e-06, bounds=(1e-07, 1e-05)\n", - " sld: value=2.0, bounds=(0.5, 4.0)\n", - " thickness: value=250.0, bounds=(100, 400)\n", - " scale: value=1.0, bounds=(0.8, 1.2)\n" - ] - } - ], + "metadata": {}, + "outputs": [], "source": [ "# ---- Create a monolayer model (Si / Film / D₂O) ----------------------------\n", "si = Material(sld=2.07, isld=0.0, name='Si')\n", @@ -204,25 +152,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "991e1169", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:09.974614Z", - "iopub.status.busy": "2026-05-29T06:29:09.974614Z", - "iopub.status.idle": "2026-05-29T06:29:09.982333Z", - "shell.execute_reply": "2026-05-29T06:29:09.982333Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitter ready with minimizer: Bumps\n" - ] - } - ], + "metadata": {}, + "outputs": [], "source": [ "# ---- Set up the calculator and fitter ---------------------------------------\n", "interface = CalculatorFactory()\n", @@ -238,36 +171,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "eb0f989e", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:09.983788Z", - "iopub.status.busy": "2026-05-29T06:29:09.983788Z", - "iopub.status.idle": "2026-05-29T06:29:11.760084Z", - "shell.execute_reply": "2026-05-29T06:29:11.760084Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Classical fit successful: True\n", - "Reduced χ² ≈ 73.7860402885366\n" - ] - }, - { - "data": { - "image/png": "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b5OaY0/QrZ636WfIc0cYBr5EREQ6EoyaY+/niDMZO962jcLLaATiEt0b3IuSBIVkxWWTA+oiHJcaIiIioi7zlD+MyE9VSxzLam9yKpneSF/mlvSHGV8iIiKKirZtRO1h4EtERERR0baNqD0sdSAiIiIiXWDgS0RERES6wFIHIiIi0i2XS2tVm0zRK+oD3/3792POnDk+l1955RXMnj07rOMiIiKi8Np6rKJ5MQ67w73YhiztPPeyi1CQEO7RUShEfeA7dOhQ7NixQ52vqalB//79MWPGjHAPi4iIiMIc9Er/4UpbI7It0n84XvUf3nO6Ck+s24d5k3IwPTs73MOkINNVje9bb72FadOmISkpKdxDISIiojCWN0imV4Le/n0SkRRvQozRoE4LMxJRXdeIV/9Zpu5H0SXsge8nn3yCG264Afn5+TAYDHjjjTda3eeZZ55RmVqz2YyJEydi8+bNXfpZa9as8Sl7ICIiIv2QQHZfaTVe23YSu09XIcsSr2IPb3I50xKHoxX1OFBWE7axUpSWOtTW1mLMmDG49957cfPNN7e6ffXq1ViwYAGef/55FfQuW7YMM2fOVLW62U1fQYwdOxYOh6PVYz/44AMVUIvq6mps3LgRq1at6oG9IiIiokit562y2XG2xo6a+kYUZCQhLSHW576y7LLdoanML0WXsAe+s2bNUlsgTz/9NO6//37cc8896rIEwGvXrsWf//xnPPLII+o6Tw1vW958801cc801KmvcloaGBrV5SMAsXC6X2rpKHqtpWreeg3oHzrV+cK71hfPde209dl7V7VbVNSLLEoeEODPO2+yornPg4BkrhmQnq44OHnV2J2JjDLDEx3C+e4mOzlPYA9+22O12bN26FT/72c+arzMajZg+fTo2bdrU6TKHBx54oN37LV68GI8++mir68+ePYv6+np0Z0KqqqrUH03ZB4penGv94FzrC+e7d3JpGl74+AgqaurQNzUeBrgQY9CQGBeD2gan6uZw7FwthsZIGweDmt8zVQ0YkGZCqsGGsrILyTCKXFartfcHvuXl5XA6ncjJyfG5Xi7v27evw88jf6ikLvi1115r974SZEtphXfGt6CgAFlZWUhJSenWH0ypG5Ln4R/M6Ma51g/Otb5wvnunfaVWnLI6kJuWCHP8hbCnsI8RB6WNmdMFm92JBqcRMTEGlNfYkZFs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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "metadata": {}, + "outputs": [], "source": [ "# ---- Classical fit first ----------------------------------------------------\n", "# A classical optimisation gives a good starting point and a sanity check\n", @@ -296,61 +203,44 @@ "cell_type": "code", "execution_count": null, "id": "20c9b0e0", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:29:11.762093Z", - "iopub.status.busy": "2026-05-29T06:29:11.762093Z", - "iopub.status.idle": "2026-05-29T06:30:41.903328Z", - "shell.execute_reply": "2026-05-29T06:30:41.903328Z" - } - }, - "outputs": [ - { - "ename": "TypeError", - "evalue": "Fitter.mcmc_sample() got an unexpected keyword argument 'chains'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# ---- Bayesian MCMC sampling -------------------------------------------------\u001b[39;00m\n\u001b[32m 2\u001b[39m \u001b[38;5;66;03m# ``MultiFitter.mcmc_sample()`` delegates to the BUMPS DREAM sampler.\u001b[39;00m\n\u001b[32m 3\u001b[39m \u001b[38;5;66;03m# All keyword arguments are forwarded with user-friendly names:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 7\u001b[39m \u001b[38;5;66;03m# ``chains`` ← DREAM population count (alias for ``pop``)\u001b[39;00m\n\u001b[32m 8\u001b[39m \u001b[38;5;66;03m# ``population``← BUMPS‑native ``pop`` for advanced users\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m posterior_dict = \u001b[43mfitter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmcmc_sample\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43msamples\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m2000\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Short for demo; use 20 k+ in production\u001b[39;49;00m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mburn\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m500\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mthin\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m10\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m)\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33mDREAM sampling complete.\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 18\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m'\u001b[39m\u001b[33m Posterior shape : \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mposterior_dict[\u001b[33m\"\u001b[39m\u001b[33mdraws\u001b[39m\u001b[33m\"\u001b[39m].shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~\\projects\\easy\\ERA\\reflectometry-lib\\src\\easyreflectometry\\fitting.py:451\u001b[39m, in \u001b[36mMultiFitter.mcmc_sample\u001b[39m\u001b[34m(self, data, samples, burn, thin, chains, population, objective, initializer, resume_state, progress_callback, abort_test)\u001b[39m\n\u001b[32m 449\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m initializer \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 450\u001b[39m sampler_kwargs[\u001b[33m'\u001b[39m\u001b[33minit\u001b[39m\u001b[33m'\u001b[39m] = initializer\n\u001b[32m--> \u001b[39m\u001b[32m451\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43measy_science_multi_fitter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmcmc_sample\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 452\u001b[39m \u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m=\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 453\u001b[39m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m=\u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 454\u001b[39m \u001b[43m \u001b[49m\u001b[43mweights\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdy\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 455\u001b[39m \u001b[43m \u001b[49m\u001b[43msamples\u001b[49m\u001b[43m=\u001b[49m\u001b[43msamples\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 456\u001b[39m \u001b[43m \u001b[49m\u001b[43mburn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mburn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 457\u001b[39m \u001b[43m \u001b[49m\u001b[43mthin\u001b[49m\u001b[43m=\u001b[49m\u001b[43mthin\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 458\u001b[39m \u001b[43m \u001b[49m\u001b[43mchains\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchains\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 459\u001b[39m \u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 460\u001b[39m \u001b[43m \u001b[49m\u001b[43mresume_state\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresume_state\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 461\u001b[39m \u001b[43m \u001b[49m\u001b[43msampler_kwargs\u001b[49m\u001b[43m=\u001b[49m\u001b[43msampler_kwargs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 462\u001b[39m \u001b[43m \u001b[49m\u001b[43mprogress_callback\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprogress_callback\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 463\u001b[39m \u001b[43m \u001b[49m\u001b[43mabort_test\u001b[49m\u001b[43m=\u001b[49m\u001b[43mabort_test\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 464\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[31mTypeError\u001b[39m: Fitter.mcmc_sample() got an unexpected keyword argument 'chains'" - ] - } - ], + "metadata": {}, + "outputs": [], "source": [ "# ---- Bayesian MCMC sampling -------------------------------------------------\n", "# ``MultiFitter.mcmc_sample()`` delegates to the BUMPS DREAM sampler.\n", "# All keyword arguments are forwarded with user-friendly names:\n", "# ``samples`` ← total retained samples\n", - "# ``burn`` ← burn‑in steps\n", + "# ``burn`` ← burn-in steps\n", "# ``thin`` ← thinning interval\n", - "# ``population``← BUMPS‑native ``pop`` for advanced users\n", + "# ``population``← BUMPS-native ``pop`` for advanced users\n", + "#\n", + "# We deliberately start with a *very* short run. It finishes in seconds but is\n", + "# far too short to trust — which is exactly the situation the \"extend the chain\"\n", + "# section below exists to fix. In production you would ask for 20 k+ samples.\n", "\n", "posterior_dict = fitter.mcmc_sample(\n", " data,\n", - " samples=2000, # Short for demo; use 20 k+ in production\n", - " burn=500,\n", + " samples=500, # Deliberately too short — extended later in this notebook\n", + " burn=100,\n", " thin=10,\n", ")\n", "\n", "print('DREAM sampling complete.')\n", "print(f' Posterior shape : {posterior_dict[\"draws\"].shape}')\n", - "print(f' Parameters : {posterior_dict[\"param_names\"]}')" + "print(f' Parameters : {posterior_dict[\"param_names\"]}')\n", + "print()\n", + "print(\n", + " 'Note: the retained draws are fewer than samples/thin. BUMPS trims the\\n'\n", + " 'chain at a detected burn point and drops outlier chains, so the number of\\n'\n", + " 'rows is not predictable from the arguments — read it off the array.'\n", + ")" ] }, { "cell_type": "code", "execution_count": null, "id": "f23934a0", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:41.905335Z", - "iopub.status.busy": "2026-05-29T06:30:41.905335Z", - "iopub.status.idle": "2026-05-29T06:30:41.908528Z", - "shell.execute_reply": "2026-05-29T06:30:41.908528Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Wrap in PosteriorResults -----------------------------------------------\n", @@ -372,14 +262,7 @@ "cell_type": "code", "execution_count": null, "id": "ef300cb1", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:41.909855Z", - "iopub.status.busy": "2026-05-29T06:30:41.909855Z", - "iopub.status.idle": "2026-05-29T06:30:41.913882Z", - "shell.execute_reply": "2026-05-29T06:30:41.913882Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Posterior summary table ------------------------------------------------\n", @@ -388,6 +271,248 @@ "print(posterior.summary())" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "34e3cc3e", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Gelman-Rubin R-hat convergence diagnostic ------------------------------\n", + "# R-hat compares the variance *between* DREAM's parallel chains with the\n", + "# variance *within* each one. Values close to 1.0 mean the chains have mixed\n", + "# and agree on the same posterior; the usual rule of thumb is R̂ < 1.1.\n", + "#\n", + "# ``posterior.gelman_rubin()`` needs draws pre-split into chains, shape\n", + "# ``(n_chains, n_draws, n_params)``. ``mcmc_sample()`` returns the draws\n", + "# already pooled into a flat ``(n_samples, n_params)`` array, so we ask the\n", + "# BUMPS state itself — it still knows the individual chains.\n", + "\n", + "\n", + "def rhat_table(state, param_names):\n", + " \"\"\"R-hat per parameter, read from the chain-aware BUMPS state.\"\"\"\n", + " return dict(zip(param_names, state.gelman()))\n", + "\n", + "\n", + "rhat_short = rhat_table(posterior.sampler_state, posterior.param_names)\n", + "\n", + "print('Gelman-Rubin R-hat after the short run:')\n", + "for name, r in rhat_short.items():\n", + " flag = ' ✓' if r < 1.1 else ' ⚠ not converged'\n", + " print(f' {name:<30s} R̂ = {r:.3f}{flag}')\n", + "\n", + "# DREAM is stochastic and unseeded, so the exact values differ run to run.\n", + "n_bad = sum(r >= 1.1 for r in rhat_short.values())\n", + "if n_bad:\n", + " print(f'\\n{n_bad} parameter(s) above 1.1 — this chain is not converged and needs more samples.')\n", + "else:\n", + " print(\n", + " f'\\nR̂ passes, but this chain holds only {posterior.draws.shape[0]} draws — '\n", + " 'far too few to rely on,\\nso every posterior estimate from it is coarse. '\n", + " 'Either way, the answer is more samples.'\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "223f79f1", + "metadata": {}, + "source": [ + "## Extending the chain\n", + "\n", + "The short run above is not something to draw conclusions from — it usually\n", + "fails the R̂ < 1.1 check outright, and even when it scrapes past it, it holds\n", + "only a few dozen draws. The fix is more samples, but restarting from scratch\n", + "would throw away the work already done and pay the burn-in cost a second time.\n", + "\n", + "Instead, **continue the existing chain**. `MultiFitter.mcmc_sample()` keeps the\n", + "underlying `Sampler` on `fitter.sampler`, and `Sampler.extend()` picks the chain\n", + "up exactly where DREAM left off:\n", + "\n", + "```python\n", + "extended = fitter.sampler.extend(additional_samples=8000, thin=10)\n", + "```\n", + "\n", + "`extend()` runs with `burn=0` — re-burning an already-converged chain would be a\n", + "mistake, and BUMPS forces it to 0 on resume anyway. It also grows DREAM's\n", + "fixed-size ring buffer by exactly `additional_samples`, so none of the existing\n", + "draws are evicted.\n", + "\n", + "### What \"improvement\" does and does not mean here\n", + "\n", + "Two things get better, and one thing deliberately does not:\n", + "\n", + "* **R̂ drops** — the chains mix and settle onto the same posterior.\n", + "* **The Monte-Carlo error shrinks** — with more draws the posterior *estimate*\n", + " (mean, credible interval, histogram shape) stops moving from run to run.\n", + "* **The posterior width does _not_ shrink.** The spread of a parameter is set by\n", + " the data and the model, not by how long you sample. If the credible interval\n", + " collapsed as we added samples, that would be a bug, not a win. What improves is\n", + " how precisely we know that interval.\n", + "\n", + "DREAM is stochastic and this notebook does not seed it, so the exact numbers\n", + "below change on every run. The direction of travel does not." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5d26166", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Continue the existing chain --------------------------------------------\n", + "# ``extend()`` mutates the sampler's BUMPS state in place, so snapshot anything\n", + "# we want to compare against first. ``rhat_short`` (plain floats) was already\n", + "# captured above; the draws need an explicit copy.\n", + "\n", + "draws_short = np.array(posterior.draws, copy=True)\n", + "n_short = draws_short.shape[0]\n", + "\n", + "extended_results = fitter.sampler.extend(\n", + " additional_samples=8000, # Added on top of the original 2000\n", + " thin=10,\n", + ")\n", + "\n", + "posterior_extended = PosteriorResults(\n", + " draws=extended_results.draws,\n", + " param_names=extended_results.param_names,\n", + " logp=extended_results.logp,\n", + " sampler_state=extended_results.state,\n", + ")\n", + "\n", + "print('Chain extended.')\n", + "print(f' Retained draws before : {n_short}')\n", + "print(f' Retained draws after : {posterior_extended.draws.shape[0]}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6b17af8", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Did convergence actually improve? --------------------------------------\n", + "# The headline check: R-hat before vs after.\n", + "\n", + "rhat_extended = rhat_table(posterior_extended.sampler_state, posterior_extended.param_names)\n", + "\n", + "print(f'{\"parameter\":<32s} {\"short\":>8s} {\"extended\":>10s}')\n", + "print('-' * 54)\n", + "for name in posterior_extended.param_names:\n", + " before, after = rhat_short[name], rhat_extended[name]\n", + " flag = ' ✓' if after < 1.1 else ' ⚠'\n", + " print(f'{name:<32s} {before:8.3f} {after:10.3f}{flag}')\n", + "\n", + "n_bad_before = sum(r >= 1.1 for r in rhat_short.values())\n", + "n_bad_after = sum(r >= 1.1 for r in rhat_extended.values())\n", + "print(f'\\nParameters failing R̂ < 1.1: {n_bad_before} → {n_bad_after}')\n", + "print(f'Worst R̂ across parameters: {max(rhat_short.values()):.3f} → {max(rhat_extended.values()):.3f}')\n", + "\n", + "if n_bad_after == 0 and n_bad_before > 0:\n", + " print('\\nThe extended chain has converged; the short one had not.')\n", + "elif n_bad_after == 0:\n", + " print('\\nBoth chains pass R̂, but the extended one does so with far more draws behind it.')\n", + "else:\n", + " print('\\nStill above threshold — extend again, or revisit the model and its bounds.')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f620d42d", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Side-by-side posterior statistics --------------------------------------\n", + "# ``extend()`` returns the parameters in the same order as the original run, so\n", + "# the columns line up — but map by name rather than trusting the index.\n", + "\n", + "col_short = {name: i for i, name in enumerate(posterior.param_names)}\n", + "col_ext = {name: i for i, name in enumerate(posterior_extended.param_names)}\n", + "\n", + "\n", + "def ci_width(column, alpha=0.95):\n", + " lo, hi = np.percentile(column, [100 * (1 - alpha) / 2, 100 * (1 + alpha) / 2])\n", + " return hi - lo\n", + "\n", + "\n", + "header = (\n", + " f'{\"parameter\":<32s} {\"mean (short)\":>13s} {\"mean (ext)\":>13s} {\"shift\":>8s} {\"95% w (short)\":>14s} {\"95% w (ext)\":>13s}'\n", + ")\n", + "print(header)\n", + "print('-' * len(header))\n", + "\n", + "for name in posterior_extended.param_names:\n", + " a = draws_short[:, col_short[name]]\n", + " b = posterior_extended.draws[:, col_ext[name]]\n", + " # Mean shift expressed in extended-posterior standard deviations: how far the\n", + " # short run's answer sits from the better-resolved one, in units that matter.\n", + " shift = abs(np.mean(a) - np.mean(b)) / np.std(b)\n", + " print(f'{name:<32s} {np.mean(a):13.5g} {np.mean(b):13.5g} {shift:7.2f}σ {ci_width(a):14.4g} {ci_width(b):13.4g}')\n", + "\n", + "print(\n", + " '\\nRead this alongside the R̂ table, not on its own. The credible intervals do\\n'\n", + " 'not systematically shrink — they should not, since posterior width is set by\\n'\n", + " 'the data, not by sampling effort. What extending buys is trust: the means\\n'\n", + " 'stop drifting and the marginals below are resolved by many more draws.'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67c37350", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Visual overlay: marginals, short vs extended ----------------------------\n", + "# Same posterior, better resolved. The short run's histogram is ragged because\n", + "# it is built from few draws; the extended one traces a smooth marginal over the\n", + "# same range. Densities are normalised so the two are comparable despite the\n", + "# very different sample counts.\n", + "\n", + "n_params = len(posterior_extended.param_names)\n", + "fig, axes = plt.subplots(1, n_params, figsize=(4 * n_params, 3.2))\n", + "axes = np.atleast_1d(axes)\n", + "\n", + "for ax, name in zip(axes, posterior_extended.param_names):\n", + " a = draws_short[:, col_short[name]]\n", + " b = posterior_extended.draws[:, col_ext[name]]\n", + " bins = np.histogram_bin_edges(np.concatenate([a, b]), bins=30)\n", + " ax.hist(a, bins=bins, density=True, alpha=0.55, label=f'short (n={a.shape[0]})')\n", + " ax.hist(b, bins=bins, density=True, alpha=0.55, label=f'extended (n={b.shape[0]})')\n", + " ax.set_title(name, fontsize=9)\n", + " ax.set_ylabel('density')\n", + " ax.legend(fontsize=8)\n", + " ax.grid(True, alpha=0.3)\n", + "\n", + "fig.suptitle('Marginal posterior: original chain vs extended chain')\n", + "fig.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e46c3dd4", + "metadata": {}, + "outputs": [], + "source": [ + "# ---- Adopt the extended chain for the rest of the notebook -------------------\n", + "# Everything below (corner plots, credible intervals, posterior-predictive\n", + "# checks) now runs on the converged chain. ``posterior_short`` is kept around\n", + "# in case you want to re-run the comparisons above.\n", + "\n", + "posterior_short = posterior\n", + "posterior = posterior_extended\n", + "\n", + "print(posterior)\n", + "print()\n", + "print(posterior.summary())" + ] + }, { "cell_type": "markdown", "id": "d1f0a300", @@ -413,14 +538,7 @@ "cell_type": "code", "execution_count": null, "id": "5b9d3c2a", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:41.914887Z", - "iopub.status.busy": "2026-05-29T06:30:41.914887Z", - "iopub.status.idle": "2026-05-29T06:30:43.463799Z", - "shell.execute_reply": "2026-05-29T06:30:43.463252Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Marginal posterior distributions ---------------------------------------\n", @@ -448,14 +566,7 @@ "cell_type": "code", "execution_count": null, "id": "e759a2a0", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:43.464801Z", - "iopub.status.busy": "2026-05-29T06:30:43.464801Z", - "iopub.status.idle": "2026-05-29T06:30:43.847435Z", - "shell.execute_reply": "2026-05-29T06:30:43.847435Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Corner plot ------------------------------------------------------------\n", @@ -470,14 +581,7 @@ "cell_type": "code", "execution_count": null, "id": "593f5ed3", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:43.852778Z", - "iopub.status.busy": "2026-05-29T06:30:43.852778Z", - "iopub.status.idle": "2026-05-29T06:30:43.905089Z", - "shell.execute_reply": "2026-05-29T06:30:43.905089Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Trace plot -------------------------------------------------------------\n", @@ -492,14 +596,7 @@ "cell_type": "code", "execution_count": null, "id": "3049e68a", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:43.906601Z", - "iopub.status.busy": "2026-05-29T06:30:43.906601Z", - "iopub.status.idle": "2026-05-29T06:30:43.912231Z", - "shell.execute_reply": "2026-05-29T06:30:43.911707Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Credible intervals -----------------------------------------------------\n", @@ -524,14 +621,7 @@ "cell_type": "code", "execution_count": null, "id": "806bf47a", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:43.913735Z", - "iopub.status.busy": "2026-05-29T06:30:43.913735Z", - "iopub.status.idle": "2026-05-29T06:30:44.004052Z", - "shell.execute_reply": "2026-05-29T06:30:44.004052Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Pairwise focus: thickness vs SLD ---------------------------------------\n", @@ -548,49 +638,11 @@ "fig.show()" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "34e3cc3e", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:44.006603Z", - "iopub.status.busy": "2026-05-29T06:30:44.006603Z", - "iopub.status.idle": "2026-05-29T06:30:44.010758Z", - "shell.execute_reply": "2026-05-29T06:30:44.010226Z" - } - }, - "outputs": [], - "source": [ - "# ---- Gelman-Rubin R‑hat convergence diagnostic ------------------------------\n", - "# Requires ``arviz`` and at least 2 chains. Values close to 1.0 indicate\n", - "# good convergence.\n", - "\n", - "try:\n", - " rhat = posterior.gelman_rubin()\n", - " print('Gelman-Rubin R‑hat:')\n", - " for name, r in rhat.items():\n", - " flag = ' ✓' if r < 1.1 else ' ⚠'\n", - " print(f' {name:<30s} R̂ = {r:.3f}{flag}')\n", - "except ValueError:\n", - " print(\n", - " 'Skipped: Gelman-Rubin R‑hat requires at least 2 chains. '\n", - " 'Run with multiple DREAM populations to obtain multi-chain draws.'\n", - " )" - ] - }, { "cell_type": "code", "execution_count": null, "id": "c7e5816e", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:44.012760Z", - "iopub.status.busy": "2026-05-29T06:30:44.012760Z", - "iopub.status.idle": "2026-05-29T06:30:45.165079Z", - "shell.execute_reply": "2026-05-29T06:30:45.165079Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Posterior-predictive reflectivity --------------------------------------\n", @@ -630,14 +682,7 @@ "cell_type": "code", "execution_count": null, "id": "ef27b8ec", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:45.166642Z", - "iopub.status.busy": "2026-05-29T06:30:45.166642Z", - "iopub.status.idle": "2026-05-29T06:30:45.413146Z", - "shell.execute_reply": "2026-05-29T06:30:45.413146Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Posterior-predictive SLD profile ---------------------------------------\n", @@ -671,14 +716,7 @@ "cell_type": "code", "execution_count": null, "id": "37e78b4e", - "metadata": { - "execution": { - "iopub.execute_input": "2026-05-29T06:30:45.415149Z", - "iopub.status.busy": "2026-05-29T06:30:45.415149Z", - "iopub.status.idle": "2026-05-29T06:30:45.419700Z", - "shell.execute_reply": "2026-05-29T06:30:45.419700Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "# ---- Summary ----------------------------------------------------------------\n", @@ -688,13 +726,17 @@ "print()\n", "print('API surface demonstrated:')\n", "print(' MultiFitter.mcmc_sample(data, samples=, burn=, thin=)')\n", + "print(' MultiFitter.sampler — the Sampler behind the last run')\n", + "print(' .extend(additional_samples=, thin=)')\n", + "print(' — continue the chain, no re-burn')\n", + "print(' .state.gelman() — chain-aware R̂ (works on pooled draws)')\n", "print(' PosteriorResults(draws, param_names, logp=, sampler_state=)')\n", "print(' .summary() — formatted parameter table')\n", "print(' .distribution() — per-parameter marginal Plotly figure')\n", "print(' .corner() — pairwise correlation Plotly figure')\n", "print(' .trace() — MCMC chain trace plot')\n", "print(' .credible_interval(alpha) — equal-tailed credible intervals')\n", - "print(' .gelman_rubin() — R̂ convergence diagnostic')\n", + "print(' .gelman_rubin() — R̂ for draws pre-split into chains')\n", "print()\n", "print(' Standalone functions (work on raw dict; the plot helpers return')\n", "print(' the same interactive Plotly figures as the App):')\n", @@ -706,7 +748,8 @@ "print(' posterior_predictive_reflectivity(draws, names, model, q, n)')\n", "print(' posterior_predictive_sld_profile(draws, names, model, n)')\n", "print()\n", - "print('The high-level API provides clean, safe access to BUMPS DREAM sampling.')" + "print('Workflow: fit → sample short → check R̂ → extend until converged → analyse.')\n", + "print('Extending continues the existing chain, so the burn-in is paid only once.')" ] } ], @@ -726,7 +769,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.11" + "version": "3.12.12" } }, "nbformat": 4, diff --git a/docs/docs/tutorials/simulation/bilayer.ipynb b/docs/docs/tutorials/simulation/bilayer.ipynb index 987cd8e1..5f37b010 100644 --- a/docs/docs/tutorials/simulation/bilayer.ipynb +++ b/docs/docs/tutorials/simulation/bilayer.ipynb @@ -331,7 +331,7 @@ "q = np.linspace(0.005, 0.3, 500)\n", "\n", "# Calculate reflectometry\n", - "reflectivity = model.interface().reflectivity_profile(q, model.unique_name)\n", + "reflectivity = model.interface().reflectity_profile(q, model.unique_name)\n", "\n", "# Plot\n", "plt.figure(figsize=(10, 6))\n", @@ -391,7 +391,7 @@ "outputs": [], "source": [ "# First, compute reflectivity with current conformal roughness (3.0 Å)\n", - "reflectivity_conformal = model.interface().reflectivity_profile(q, model.unique_name)\n", + "reflectivity_conformal = model.interface().reflectity_profile(q, model.unique_name)\n", "\n", "# Disable conformal roughness to allow independent roughness per layer\n", "bilayer.conformal_roughness = False\n", @@ -406,7 +406,7 @@ "bilayer.back_head_layer.roughness.value = 4.0\n", "\n", "# Compute reflectivity with variable roughness\n", - "reflectivity_variable_roughness = model.interface().reflectivity_profile(q, model.unique_name)\n", + "reflectivity_variable_roughness = model.interface().reflectity_profile(q, model.unique_name)\n", "\n", "# Plot comparison\n", "plt.figure(figsize=(10, 6))\n", @@ -629,8 +629,8 @@ "outputs": [], "source": [ "# Calculate reflectivity for both contrasts\n", - "reflectivity_d2o = model.interface().reflectivity_profile(q, model.unique_name)\n", - "reflectivity_h2o = model_h2o.interface().reflectivity_profile(q, model_h2o.unique_name)\n", + "reflectivity_d2o = model.interface().reflectity_profile(q, model.unique_name)\n", + "reflectivity_h2o = model_h2o.interface().reflectity_profile(q, model_h2o.unique_name)\n", "\n", "plt.figure(figsize=(10, 6))\n", "plt.semilogy(q, reflectivity_d2o, 'b-', linewidth=2, label='D₂O contrast')\n", diff --git a/docs/docs/tutorials/simulation/magnetism.ipynb b/docs/docs/tutorials/simulation/magnetism.ipynb index ef226c41..8efdb9e4 100644 --- a/docs/docs/tutorials/simulation/magnetism.ipynb +++ b/docs/docs/tutorials/simulation/magnetism.ipynb @@ -252,7 +252,7 @@ "model.resolution_function = PercentageFwhm(0)\n", "model_interface = model.interface()\n", "model_interface.magnetism = False\n", - "model_data_no_magnetism_ref1d_easy = model.interface().reflectivity_profile(\n", + "model_data_no_magnetism_ref1d_easy = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -284,7 +284,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.include_magnetism = True\n", - "model_data_magnetism = model.interface().reflectivity_profile(\n", + "model_data_magnetism = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -301,7 +301,7 @@ "model_interface._wrapper.update_layer(\n", " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", ")\n", - "model_data_magnetism_layer_1 = model.interface().reflectivity_profile(\n", + "model_data_magnetism_layer_1 = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -365,7 +365,7 @@ "model_interface._wrapper.update_layer(\n", " list(model_interface._wrapper.storage['layer'].keys())[2], magnetism_rhoM=5, magnetism_thetaM=175\n", ")\n", - "model_data_magnetism_easy = model.interface().reflectivity_profile(\n", + "model_data_magnetism_easy = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -478,7 +478,7 @@ "interface.switch('refnx')\n", "model.interface = interface\n", "model_interface = model.interface()\n", - "model_data_no_magnetism_refnx = model.interface().reflectivity_profile(\n", + "model_data_no_magnetism_refnx = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -488,7 +488,7 @@ "interface.switch('refl1d')\n", "model.interface = interface\n", "model_interface = model.interface()\n", - "model_data_no_magnetism_ref1d = model.interface().reflectivity_profile(\n", + "model_data_no_magnetism_ref1d = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -518,7 +518,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.magnetism = True\n", - "model_data_magnetism = model.interface().reflectivity_profile(\n", + "model_data_magnetism = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -529,7 +529,7 @@ "model.interface = interface\n", "model_interface = model.interface()\n", "model_interface.magnetism = False\n", - "model_data_no_magnetism = model.interface().reflectivity_profile(\n", + "model_data_no_magnetism = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", diff --git a/docs/docs/tutorials/simulation/resolution_functions.ipynb b/docs/docs/tutorials/simulation/resolution_functions.ipynb index cc7abe10..d46a76cb 100644 --- a/docs/docs/tutorials/simulation/resolution_functions.ipynb +++ b/docs/docs/tutorials/simulation/resolution_functions.ipynb @@ -310,7 +310,7 @@ " num=1000,\n", " )\n", " model.resolution_function = resolution_function_dict[key]\n", - " model_data = model.interface().reflectivity_profile(\n", + " model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", " )\n", @@ -363,14 +363,14 @@ ")\n", "\n", "model.resolution_function = resolution_function_dict[key]\n", - "model_data = model.interface().reflectivity_profile(\n", + "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", "plt.plot(model_coords, model_data, 'k-', label='Variable', linewidth=5)\n", "\n", "model.resolution_function = PercentageFwhm(1.0)\n", - "model_data = model.interface().reflectivity_profile(\n", + "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -402,7 +402,7 @@ ")\n", "\n", "model.resolution_function = resolution_function_dict[key]\n", - "model_data = model.interface().reflectivity_profile(\n", + "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", @@ -415,7 +415,7 @@ "data_points.append(reference_data) # R\n", "data_points.append(reference_variances) # sQz (variance of Qz)\n", "model.resolution_function = Pointwise(q_data_points=data_points)\n", - "model_data = model.interface().reflectivity_profile(\n", + "model_data = model.interface().reflectity_profile(\n", " model_coords,\n", " model.unique_name,\n", ")\n", diff --git a/pixi.lock b/pixi.lock index 983bc0bd..36a67a04 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,21 +1,8 @@ version: 7 platforms: - name: linux-64 - virtual-packages: - - __unix=0=0 - - __linux=4.18 - - __glibc=2.28 - - __archspec=0=x86_64 -- name: p1 - subdir: osx-arm64 - virtual-packages: - - __osx=14.0 - - __unix=0=0 - - __archspec=0=m1 +- name: osx-arm64 - name: win-64 - virtual-packages: - - __win=10.0 - - __archspec=0=x86_64 environments: default: channels: @@ -202,8 +189,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -339,7 +326,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - p1: + osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -513,8 +500,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -814,8 +801,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -1137,8 +1124,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl @@ -1272,7 +1259,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - p1: + osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda @@ -1442,8 +1429,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl @@ -1737,8 +1724,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2060,8 +2047,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2197,7 +2184,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - p1: + osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -2371,8 +2358,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2672,8 +2659,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: ./ - - pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 + - pypi: . + - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -3083,7 +3070,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - p1: + osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -8310,11 +8297,11 @@ packages: purls: [] size: 388453 timestamp: 1764777142545 -- pypi: ./ +- pypi: . name: easyreflectometry requires_dist: - bumps - - easyscience @ git+https://github.com/easyscience/corelib.git@develop + - easyscience @ git+https://github.com/easyscience/corelib.git@bayesian_extend - orsopy - plotly - pooch @@ -8358,9 +8345,9 @@ packages: - validate-pyproject[all] ; extra == 'dev' - versioningit ; extra == 'dev' requires_python: '>=3.11' -- pypi: git+https://github.com/easyscience/corelib.git?rev=develop#aadbd4891b94f6aa18187d48be8c2ab6f81113b0 +- pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca name: easyscience - version: 2.3.1+dev8 + version: 2.4.0+dev17 requires_dist: - asteval - bumps diff --git a/pixi.toml b/pixi.toml index b0fb2b8d..ab6c977e 100644 --- a/pixi.toml +++ b/pixi.toml @@ -94,7 +94,15 @@ user = { features = ['py-max', 'user'] } unit-tests = 'python -m pytest tests/unit/ --color=yes -v' functional-tests = 'python -m pytest tests/functional/ --color=yes -v' -integration-tests = 'python -m pytest tests/integration/ --color=yes -n auto -v' +# No -n auto: importing easyreflectometry pulls in arviz, and arviz 0.23.4 +# (py-311-env) writes a "warn once per day" stamp file on import via a +# _atomic_write_text() that is not atomic -- every process writes the same +# fixed `daily_warning.tmp` and renames it onto `daily_warning`. Concurrent +# xdist workers therefore race on that rename: FileNotFoundError on Linux, +# PermissionError (WinError 32) on Windows. The real fix is +# to stop importing arviz in easyreflectometry/__init__.py, after which +# xdist can come back. +integration-tests = 'python -m pytest tests/integration/ --color=yes -v' notebook-tests = 'python -m pytest --nbmake docs/docs/tutorials/**/ --nbmake-timeout=1200 --color=yes -n auto -v' test = { depends-on = ['unit-tests'] } diff --git a/src/easyreflectometry/analysis/bayesian.py b/src/easyreflectometry/analysis/bayesian.py index 39389a84..17ab252c 100644 --- a/src/easyreflectometry/analysis/bayesian.py +++ b/src/easyreflectometry/analysis/bayesian.py @@ -1332,8 +1332,9 @@ def load_posterior(path: str, skip: int = 0) -> 'PosteriorResults': """Reload a trace saved by :func:`save_posterior` into a :class:`PosteriorResults`. - The returned object's ``sampler_state`` can be fed back into - ``MultiFitter.mcmc_sample(..., resume_state=...)`` to extend the chain. + The returned object's ``sampler_state`` can be fed back into the core + ``Sampler`` (via ``Sampler.load_state(...)`` / ``Sampler.extend(...)``) + to extend the chain. :param path: File path prefix used in :func:`save_posterior`. :type path: str diff --git a/src/easyreflectometry/calculators/calculator_base.py b/src/easyreflectometry/calculators/calculator_base.py index 06fa5f07..e2a92804 100644 --- a/src/easyreflectometry/calculators/calculator_base.py +++ b/src/easyreflectometry/calculators/calculator_base.py @@ -189,7 +189,7 @@ def remove_item_from_model(self, item_id: str, model_id: str) -> None: """ self._wrapper.remove_item(item_id, model_id) - def reflectivity_profile(self, x_array: np.ndarray, model_id: str) -> np.ndarray: + def reflectity_profile(self, x_array: np.ndarray, model_id: str) -> np.ndarray: """Determines the reflectivity profile for the given range and model. Parameters diff --git a/src/easyreflectometry/calculators/factory.py b/src/easyreflectometry/calculators/factory.py index b1c1b170..c3e1479c 100644 --- a/src/easyreflectometry/calculators/factory.py +++ b/src/easyreflectometry/calculators/factory.py @@ -40,6 +40,6 @@ def fit_func(self) -> Callable: def __fit_func(*args, **kwargs): """Fit func.""" - return self().reflectivity_profile(*args, **kwargs) + return self().reflectity_profile(*args, **kwargs) return __fit_func diff --git a/src/easyreflectometry/calculators/refl1d/wrapper.py b/src/easyreflectometry/calculators/refl1d/wrapper.py index 7a07c917..6985d47c 100644 --- a/src/easyreflectometry/calculators/refl1d/wrapper.py +++ b/src/easyreflectometry/calculators/refl1d/wrapper.py @@ -8,8 +8,6 @@ from refl1d import names from refl1d.sample.layers import Repeat -from easyreflectometry.model import PercentageFwhm - from ..wrapper_base import WrapperBase RESOLUTION_PADDING = 3.5 @@ -205,12 +203,9 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: Reflectivity calculated at q. """ sample = _build_sample(self.storage, model_name) + # smearing() returns sigma, which is exactly what refl1d's probe.dQ expects. dq_array = self._resolution_function.smearing(q_array) - if isinstance(self._resolution_function, PercentageFwhm): - # Get percentage of Q and change from sigma to FWHM - dq_array = dq_array * q_array / 100 / (2 * np.sqrt(2 * np.log(2))) - if not self._magnetism: probe = _get_probe( q_array=q_array, diff --git a/src/easyreflectometry/calculators/refnx/wrapper.py b/src/easyreflectometry/calculators/refnx/wrapper.py index 3742d727..65dc8662 100644 --- a/src/easyreflectometry/calculators/refnx/wrapper.py +++ b/src/easyreflectometry/calculators/refnx/wrapper.py @@ -8,6 +8,7 @@ from refnx import reflect from easyreflectometry.model import PercentageFwhm +from easyreflectometry.model.resolution_functions import SIGMA_TO_FWHM from ..wrapper_base import WrapperBase @@ -191,9 +192,12 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: dq_vector = self._resolution_function.smearing(q_array) if isinstance(self._resolution_function, PercentageFwhm): - # FWHM Percentage resolution is constant given as - # For a constant resolution percentage refnx supports to pass a scalar value rather than a vector - dq_vector = dq_vector[0] + # refnx interprets a scalar x_err as a constant dq/q (FWHM percentage), + # so pass the percentage directly rather than a per-point vector. + dq_vector = self._resolution_function.constant + else: + # smearing() returns sigma; refnx expects the FWHM at each point. + dq_vector = dq_vector * SIGMA_TO_FWHM return model(x=q_array, x_err=dq_vector) diff --git a/src/easyreflectometry/fitting.py b/src/easyreflectometry/fitting.py index 4cd24004..0efaaaa5 100644 --- a/src/easyreflectometry/fitting.py +++ b/src/easyreflectometry/fitting.py @@ -10,6 +10,7 @@ import scipp as sc from easyscience.fitting import AvailableMinimizers from easyscience.fitting import FitResults +from easyscience.fitting import Sampler from easyscience.fitting.multi_fitter import MultiFitter as EasyScienceMultiFitter from easyreflectometry.data import DataSet1D @@ -194,6 +195,7 @@ def wrapped(*args, **kwargs): self._fit_results: list[FitResults] | None = None self._classical_fit_metrics: list[dict] | None = None self._objective = _validate_objective(objective) + self._sampler: Sampler | None = None def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup: """Perform the fitting and populate the DataGroups with the result. @@ -355,24 +357,6 @@ def fit_single_data_set_1d(self, data: DataSet1D, objective: str | None = None) ] return result - def record_fit_results(self, results: list[FitResults] | None) -> None: - """Record fit results produced outside this fitter instance. - - The application runs threaded fits directly on the lower-level - ``easy_science_multi_fitter`` (for progress reporting and cancellation) - rather than through :meth:`fit`. As a result, the high-level - ``_fit_results`` used by :attr:`chi2`, :attr:`reduced_chi`, and the - HTML summary's goodness-of-fit are never populated. Call this after such - a fit so those consumers reflect the latest results. Pass ``None`` to - clear. - - :param results: The list of ``FitResults`` from the completed fit, or - ``None`` to reset. - """ - self._fit_results = results - if not results: - self._classical_fit_metrics = None - def mcmc_sample( self, data: sc.DataGroup, @@ -399,12 +383,18 @@ def mcmc_sample( :param initializer: DREAM population initializer. One of ``'eps'``, ``'cov'``, ``'lhs'``, or ``'random'``. By default, None (BUMPS uses ``'eps'``). - — the population already exists in the saved state. :param progress_callback: Optional callback for progress updates during sampling. Forwarded to the core MultiFitter. - :return: Dictionary with keys ``'draws'``, ``'param_names'``, - ``'internal_bumps_object'``, and ``'logp'``. + :return: Dictionary with keys ``'draws'``, ``'param_names'``, ``'state'``, + and ``'logp'``. :raises RuntimeError: If the current minimizer is not a BUMPS instance. + + The underlying :class:`~easyscience.fitting.Sampler` is retained on + :attr:`sampler`, so the chain can be continued without re-running the + burn-in:: + + fitter.mcmc_sample(data, samples=2000, burn=500, thin=10) + extended = fitter.sampler.extend(additional_samples=8000, thin=10) """ minimizer = self.easy_science_multi_fitter.minimizer if not (hasattr(minimizer, 'package') and minimizer.package == 'bumps'): @@ -426,6 +416,14 @@ def mcmc_sample( y_vals = data['data'][f'R_{i}'].values variances = data['data'][f'R_{i}'].variances + if obj != 'mighell' and np.all(np.asarray(variances) <= 0.0): + raise ValueError( + f'Cannot run Bayesian sampling on reflectivity {i}: all points have zero variance. ' + 'The likelihood is undefined without measurement uncertainties. Supply uncertainties, ' + "or explicitly opt in to the Mighell transform with objective='mighell' " + '(a chi-square bias correction, not a true likelihood).' + ) + x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj) if stats['masked'] > 0: @@ -433,18 +431,43 @@ def mcmc_sample( f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during sampling.', UserWarning, ) + if stats.get('transformed_all_points'): + warnings.warn( + f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during sampling. ' + 'The Mighell transform is a chi-square bias correction, not a true likelihood; ' + 'posterior widths may be unreliable.', + UserWarning, + ) + elif stats['mighell_substituted'] > 0: + warnings.warn( + f'Applied Mighell substitution to {stats["mighell_substituted"]} ' + f'zero-variance point(s) in reflectivity {i} during sampling. ' + 'The Mighell transform is a chi-square bias correction, not a true likelihood; ' + 'posterior widths may be unreliable.', + UserWarning, + ) x.append(x_out) y.append(y_eff) dy.append(weights) - # Delegate the actual BUMPS/DREAM sampling to the core MultiFitter + # Delegate the actual BUMPS/DREAM sampling to the core ``Sampler``. + # The core API moved from ``MultiFitter.mcmc_sample()`` to a dedicated + # ``Sampler`` class: construct it with the configured fitter and the + # bound data, then call ``sample()``. ``Sampler`` handles the + # multi-dataset reshaping internally. sampler_kwargs = {} if initializer is not None: sampler_kwargs['init'] = initializer - return self.easy_science_multi_fitter.mcmc_sample( + + sampler = Sampler( + self.easy_science_multi_fitter, x=x, y=y, weights=dy, + ) + # Retained so the chain can be continued afterwards via ``self.sampler.extend()``. + self._sampler = sampler + results = sampler.sample( samples=samples, burn=burn, thin=thin, @@ -453,6 +476,22 @@ def mcmc_sample( progress_callback=progress_callback, abort_test=abort_test, ) + return { + 'draws': results.draws, + 'param_names': results.param_names, + 'state': results.state, + 'logp': results.logp, + } + + @property + def sampler(self) -> Sampler | None: + """The ``Sampler`` behind the most recent :meth:`mcmc_sample` call, or None. + + Holds the live BUMPS chain state, so the sampling run can be continued + with ``fitter.sampler.extend(additional_samples=...)`` instead of + starting a fresh chain. + """ + return self._sampler @property def chi2(self) -> float | None: @@ -512,3 +551,19 @@ def switch_minimizer(self, minimizer: AvailableMinimizers) -> None: Minimizer to be switched to. """ self.easy_science_multi_fitter.switch_minimizer(minimizer) + + +def _flatten_list(this_list: list) -> list: + """Flatten nested lists. + + Parameters + ---------- + this_list : list + List to be flattened. + + Returns + ------- + list + Flattened list. + """ + return np.array([item for sublist in this_list for item in sublist]) diff --git a/src/easyreflectometry/limits.py b/src/easyreflectometry/limits.py index 8962ab9b..001bba64 100644 --- a/src/easyreflectometry/limits.py +++ b/src/easyreflectometry/limits.py @@ -31,19 +31,14 @@ def apply_default_limits(parameter: Parameter, kind: str) -> None: def _apply_percentage_limits(parameter: Parameter) -> None: - """Set bounds to 50%-200% of the current value, only if current bounds are inf. - - For negative values 0.5*value > 2*value, so the candidates are ordered - to keep min <= value <= max. - """ + """Set min to 50% and max to 200% of the current value, only if current bounds are inf.""" value = parameter.value if value == 0.0: return - low, high = sorted((0.5 * value, 2.0 * value)) if np.isinf(parameter.min): - parameter.min = low + parameter.min = 0.5 * value if np.isinf(parameter.max): - parameter.max = high + parameter.max = 2.0 * value def _apply_fixed_limits(parameter: Parameter, low: float, high: float) -> None: diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index 5aa32833..da1396d0 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -148,12 +148,12 @@ def background(self, value: float) -> None: # ----- assembly management ----- - def add_assemblies(self, *assemblies: BaseAssembly) -> None: + def add_assemblies(self, *assemblies: list[BaseAssembly]) -> None: """Add assemblies to the model sample. Parameters ---------- - *assemblies : BaseAssembly + *assemblies : list[BaseAssembly] Assemblies to add to model sample. """ if not assemblies: diff --git a/src/easyreflectometry/model/resolution_functions.py b/src/easyreflectometry/model/resolution_functions.py index c723bf14..9579ad66 100644 --- a/src/easyreflectometry/model/resolution_functions.py +++ b/src/easyreflectometry/model/resolution_functions.py @@ -6,11 +6,18 @@ Gaussian distribution with a FWHM of the percentage of the q value. To convert from a sigma value to a FWHM value we use the formula FWHM = 2.35 * sigma [2 * np.sqrt(2 * np.log(2)) * sigma]. + +The :meth:`ResolutionFunction.smearing` contract returns **sigma** +(the standard deviation of the Gaussian resolution) for every resolution +type. This matches the ``sQz`` convention used by data reduction and the +natural output of :class:`Pointwise`. Each calculation engine wrapper is +responsible for converting sigma to the width convention of its backend +(FWHM for refnx, sigma for refl1d), so that vector resolutions are +interpreted consistently across engines (see GitHub issue #367). """ from __future__ import annotations -from abc import ABC from abc import abstractmethod from typing import List from typing import Optional @@ -20,10 +27,15 @@ DEFAULT_RESOLUTION_FWHM_PERCENTAGE = 5.0 +# Conversion factor between sigma and FWHM for a Gaussian: FWHM = SIGMA_TO_FWHM * sigma. +SIGMA_TO_FWHM = 2 * np.sqrt(2 * np.log(2)) + -class ResolutionFunction(ABC): +class ResolutionFunction: @abstractmethod - def smearing(self, q: Union[np.array, float]) -> np.array: ... + def smearing(self, q: Union[np.array, float]) -> np.array: + """Return the resolution as sigma (standard deviation) at each ``q``.""" + ... @abstractmethod def as_dict(self, skip: Optional[List[str]] = None) -> dict: ... @@ -52,8 +64,14 @@ def __init__(self, constant: Union[None, float] = None): self.constant = constant def smearing(self, q: Union[np.array, float]) -> np.array: - """Smearing function.""" - return np.ones(np.array(q).size) * self.constant + """Return per-point sigma values from the constant FWHM percentage. + + ``constant`` is a FWHM percentage of ``q``; it is converted to an + absolute sigma so the smearing() contract is sigma for all types. + """ + q_array = np.asarray(q, dtype=float) + fwhm = (self.constant / 100.0) * q_array + return fwhm / SIGMA_TO_FWHM def as_dict( self, skip: Optional[List[str]] = None @@ -69,8 +87,13 @@ def __init__(self, q_data_points: np.array, fwhm_values: np.array): self.fwhm_values = fwhm_values def smearing(self, q: Union[np.array, float]) -> np.array: - """Smearing function.""" - return np.interp(q, self.q_data_points, self.fwhm_values) + """Return per-point sigma values from the FWHM knots. + + The stored ``fwhm_values`` are FWHM widths; they are interpolated + onto ``q`` and converted to sigma to satisfy the smearing() contract. + """ + fwhm = np.interp(np.asarray(q, dtype=float), self.q_data_points, self.fwhm_values) + return fwhm / SIGMA_TO_FWHM def as_dict( self, skip: Optional[List[str]] = None @@ -111,10 +134,12 @@ def __init__(self, q_data_points: List[np.ndarray]): self.q_data_points = q_data_points def smearing(self, q: Optional[Union[np.ndarray, float]] = None) -> np.ndarray: - """Return the resolution width interpolated onto ``q``. + """Return the resolution sigma interpolated onto ``q``. - The width at each data point is ``sqrt(sQz)``; values are linearly - interpolated onto the requested ``q``. When ``q`` is ``None`` the widths + ``sQz`` is the variance of ``Qz``, so the sigma at each data point is + ``sqrt(sQz)``; values are linearly interpolated onto the requested + ``q``. This already satisfies the sigma smearing() contract, so no + FWHM conversion is applied. When ``q`` is ``None`` the sigma values are returned at the stored data points. """ Qz = np.asarray(self.q_data_points[0], dtype=float) diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index fe4af1bf..aa0eacf6 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -28,6 +28,7 @@ from easyreflectometry.model import Model from easyreflectometry.model import ModelCollection from easyreflectometry.model import PercentageFwhm +from easyreflectometry.model import Pointwise from easyreflectometry.sample import Layer from easyreflectometry.sample import Material from easyreflectometry.sample import MaterialCollection @@ -346,30 +347,29 @@ def path_json(self): """Path json.""" return self.path / 'project.json' - def _get_or_add_material_index(self, name: str, sld: float, isld: float) -> int: - """Return the index of the named material, adding it to the project - materials first if not present. This mutates ``self._materials``.""" - names = [material.name for material in self._materials] - if name not in names: - self._materials.add_material(Material(name=name, sld=sld, isld=isld)) - names.append(name) - return names.index(name) - def get_index_air(self) -> int: - """Index of the Air material, adding it to the project if missing.""" - return self._get_or_add_material_index('Air', sld=0.0, isld=0.0) + """Get index air.""" + if 'Air' not in [material.name for material in self._materials]: + self._materials.add_material(Material(name='Air', sld=0.0, isld=0.0)) + return [material.name for material in self._materials].index('Air') def get_index_si(self) -> int: - """Index of the Si material, adding it to the project if missing.""" - return self._get_or_add_material_index('Si', sld=2.07, isld=0.0) + """Get index si.""" + if 'Si' not in [material.name for material in self._materials]: + self._materials.add_material(Material(name='Si', sld=2.07, isld=0.0)) + return [material.name for material in self._materials].index('Si') def get_index_sio2(self) -> int: - """Index of the SiO2 material, adding it to the project if missing.""" - return self._get_or_add_material_index('SiO2', sld=3.47, isld=0.0) + """Get index sio2.""" + if 'SiO2' not in [material.name for material in self._materials]: + self._materials.add_material(Material(name='SiO2', sld=3.47, isld=0.0)) + return [material.name for material in self._materials].index('SiO2') def get_index_d2o(self) -> int: - """Index of the D2O material, adding it to the project if missing.""" - return self._get_or_add_material_index('D2O', sld=6.36, isld=0.0) + """Get index d2o.""" + if 'D2O' not in [material.name for material in self._materials]: + self._materials.add_material(Material(name='D2O', sld=6.36, isld=0.0)) + return [material.name for material in self._materials].index('D2O') def load_orso_file(self, path: Union[Path, str]) -> None: """Load an ORSO file and optionally create a model and a data from it.""" @@ -387,6 +387,7 @@ def load_orso_file(self, path: Union[Path, str]) -> None: self._experiments[0].name = 'Experiment from ORSO' self._experiments[0].model = self.models[0] self._with_experiments = True + pass def set_sample_from_orso(self, sample: Sample) -> None: """Replace the current project model collection with a single model built from an ORSO-parsed sample. @@ -521,6 +522,10 @@ def _apply_resolution_function( ) -> None: """Set the resolution function on *model* based on variance data in *experiment*. + Uses the measured per-point q-resolution (``Pointwise``) when the + experiment carries q-variance data (``xe``, i.e. sQz²); otherwise + falls back to the default 5% FWHM percentage resolution. + Parameters ---------- experiment : DataSet1D @@ -528,7 +533,10 @@ def _apply_resolution_function( model : Model The model whose resolution function is set. """ - model.resolution_function = PercentageFwhm(5.0) + if experiment.xe is not None and np.any(experiment.xe): + model.resolution_function = Pointwise(q_data_points=[experiment.x, experiment.y, experiment.xe]) + else: + model.resolution_function = PercentageFwhm(5.0) @staticmethod def _auto_set_background(experiment: DataSet1D) -> None: @@ -665,7 +673,7 @@ def model_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.arr if q_range is None: q_range = np.linspace(self.q_min, self.q_max, self.q_resolution) self.models[index].interface = self._calculator - reflectivity = self.models[index].interface().reflectivity_profile(q_range, self._models[index].unique_name) + reflectivity = self.models[index].interface().reflectity_profile(q_range, self._models[index].unique_name) return DataSet1D( name=f'Reflectivity for Model {index}', x=q_range, @@ -868,10 +876,10 @@ def as_dict(self, include_materials_not_in_model=False): self._as_dict_add_materials_not_in_model_dict(project_dict) if self._with_experiments: self._as_dict_add_experiments(project_dict) - # Read the minimizer without touching the lazy `fitter` property: - # serialization must not construct a MultiFitter as a side effect. - if self.minimizer is not None: - project_dict['fitter_minimizer'] = self.minimizer.name + if self.fitter is not None: + project_dict['fitter_minimizer'] = self.fitter.easy_science_multi_fitter.minimizer.name + elif self._minimizer_selection is not None: + project_dict['fitter_minimizer'] = self._minimizer_selection.name if self._calculator is not None: project_dict['calculator'] = self._calculator.current_interface_name if self._colors is not None: diff --git a/src/easyreflectometry/sample/elements/materials/material_mixture.py b/src/easyreflectometry/sample/elements/materials/material_mixture.py index b5b88e27..1ab76ddc 100644 --- a/src/easyreflectometry/sample/elements/materials/material_mixture.py +++ b/src/easyreflectometry/sample/elements/materials/material_mixture.py @@ -152,16 +152,17 @@ def fraction(self, value: float) -> None: # ----- derived sld / isld parameters (shared shape with Material) ----- # # These are *derived* via the constraints set up in `_materials_constraints` - # (not constructor arguments), so unlike Material there are no setters: - # their values follow the child materials and the fraction. + # (not constructor arguments) so we expose them as floats to match the + # legacy MaterialMixture API. The underlying Parameter objects remain + # available as `self._sld` / `self._isld`. @property - def sld(self) -> Parameter: - return self._sld + def sld(self) -> float: + return self._sld.value @property - def isld(self) -> Parameter: - return self._isld + def isld(self) -> float: + return self._isld.value # ----- calculator binding ----- @@ -170,8 +171,8 @@ def _get_linkable_attributes(self): Override of the inherited `BaseCore._get_linkable_attributes`, which walks `get_all_variables()` and would otherwise expose the **child** - materials' sld/isld alongside the mixed ones. The calculator's - `InterfaceFactoryTemplate.generate_bindings` + materials' sld/isld (because our own `sld` / `isld` are floats, not + Parameters). The calculator's `InterfaceFactoryTemplate.generate_bindings` matches by parameter `name`; without this override it binds to `material_a.sld` and reflectivity is computed off the wrong SLD. """ diff --git a/src/easyreflectometry/special/calculations.py b/src/easyreflectometry/special/calculations.py index 9c6e43c2..07844d3c 100644 --- a/src/easyreflectometry/special/calculations.py +++ b/src/easyreflectometry/special/calculations.py @@ -44,13 +44,11 @@ def neutron_scattering_length(formula: str) -> complex: scattering_length = 0 + 0j for key, value in formula_as_dict.items(): scattering_length += pt.elements.symbol(key).neutron.b_c * value - # b_c_i is the imaginary (absorption) part of the bound coherent - # scattering length, not the incoherent scattering length. if pt.elements.symbol(key).neutron.b_c_i: - imag = pt.elements.symbol(key).neutron.b_c_i + inc = pt.elements.symbol(key).neutron.b_c_i else: - imag = 0 - scattering_length += imag * 1j * value + inc = 0 + scattering_length += inc * 1j * value return scattering_length * 1e-5 @@ -65,7 +63,7 @@ def molecular_weight(formula: str) -> float: Returns ------- float - Molecular weight of the material in u (g/mol). + Molecular weight of the material in kilograms. """ formula_as_dict = parse_formula(formula) mw = 0 diff --git a/src/easyreflectometry/summary/html_templates.py b/src/easyreflectometry/summary/html_templates.py index fe520e2b..9df780aa 100644 --- a/src/easyreflectometry/summary/html_templates.py +++ b/src/easyreflectometry/summary/html_templates.py @@ -141,7 +141,7 @@ No. of constraints - num_constraints + num_constriants """ diff --git a/src/easyreflectometry/summary/summary.py b/src/easyreflectometry/summary/summary.py index d8df7bd2..f40f23ad 100644 --- a/src/easyreflectometry/summary/summary.py +++ b/src/easyreflectometry/summary/summary.py @@ -309,28 +309,26 @@ def _refinement_section(self) -> str: html_refinement = html_refinement.replace('num_total_params', f'{num_params}') html_refinement = html_refinement.replace('num_free_params', f'{num_free_params}') html_refinement = html_refinement.replace('num_fixed_params', f'{num_fixed_params}') - html_refinement = html_refinement.replace('num_constraints', f'{num_constraints}') + html_refinement = html_refinement.replace('num_constriants', f'{num_constraints}') return html_refinement def _compute_goodness_of_fit(self) -> str: - """Return reduced chi² as a formatted string, or 'N/A' if no fit has been run. - - The value is read from the project's fitter, which computes the reduced - chi-square directly from the raw chi-square and the global degrees of - freedom across every fitted dataset. Deriving it this way keeps the - summary independent of the per-minimizer ``reduced_chi`` / ``reduced_chi2`` - attribute naming used by the underlying ``FitResults`` objects. - """ - fitter = self._project.fitter - if fitter is None: + """Return reduced chi² as a formatted string, or 'N/A' if no fit has been run.""" + last_fit_results = getattr(self._project, '_last_fit_results', None) + if not last_fit_results: return 'N/A' try: - gof = fitter.reduced_chi + if len(last_fit_results) == 1: + gof = float(last_fit_results[0].reduced_chi2) + else: + total_chi2 = sum(float(r.chi2) for r in last_fit_results) + total_points = sum(len(r.x) for r in last_fit_results) + n_pars = last_fit_results[0].n_pars + dof = total_points - n_pars + gof = total_chi2 / dof if dof > 0 else 0.0 + return f'{gof:.4g}' except (AttributeError, TypeError, ValueError, ZeroDivisionError): return 'N/A' - if gof is None: - return 'N/A' - return f'{gof:.4g}' def _figures_section(self, interactive: bool = True) -> str: """Figures section. diff --git a/tests/calculators/refl1d/test_refl1d_calculator.py b/tests/calculators/refl1d/test_refl1d_calculator.py index a27d1f7a..50de2db4 100644 --- a/tests/calculators/refl1d/test_refl1d_calculator.py +++ b/tests/calculators/refl1d/test_refl1d_calculator.py @@ -27,7 +27,7 @@ def test_init(self): assert_equal(p._model_link['background'], 'bkg') assert_equal(p.name, 'refl1d') - def test_reflectivity_profile(self): + def test_reflectity_profile(self): p = Refl1d() p._wrapper.create_material('Material1') p._wrapper.update_material('Material1', rho=0.000, irho=0.000) @@ -63,7 +63,7 @@ def test_reflectivity_profile(self): 1.3093e-07, 1.0520e-07, ] - assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected, decimal=4) + assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected, decimal=4) def test_calculate2(self): p = Refl1d() @@ -95,7 +95,7 @@ def test_calculate2(self): p._wrapper.add_item('Item3', 'MyModel') p._wrapper.update_item('Item2', repeat=10) q = np.linspace(0.001, 0.3, 10) - actual = p.reflectivity_profile(q, 'MyModel') + actual = p.reflectity_profile(q, 'MyModel') expected = [ 9.9949e-01, 8.7414e-03, @@ -140,7 +140,7 @@ def test_calculate_magnetic(self): p._wrapper.add_item('Item2', 'MyModel') p._wrapper.add_item('Item3', 'MyModel') q = np.linspace(0.001, 0.3, 10) - actual = p.reflectivity_profile(q, 'MyModel') + actual = p.reflectity_profile(q, 'MyModel') expected = [ 9.99491251e-01, 1.08413641e-02, diff --git a/tests/calculators/refnx/test_refnx_calculator.py b/tests/calculators/refnx/test_refnx_calculator.py index e4efae68..baeb9296 100644 --- a/tests/calculators/refnx/test_refnx_calculator.py +++ b/tests/calculators/refnx/test_refnx_calculator.py @@ -27,7 +27,7 @@ def test_init(self): assert_equal(p._model_link['background'], 'bkg') assert_equal(p.name, 'refnx') - def test_reflectivity_profile(self): + def test_reflectity_profile(self): p = Refnx() p._wrapper.create_material('Material1') p._wrapper.update_material('Material1', real=0.000, imag=0.000) @@ -62,7 +62,7 @@ def test_reflectivity_profile(self): 1.26726993e-07, 1.01842852e-07, ] - assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected) + assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected) def test_calculate2(self): p = Refnx() @@ -105,7 +105,7 @@ def test_calculate2(self): 3.4981523e-07, 2.5424356e-07, ] - assert_almost_equal(p.reflectivity_profile(q, 'MyModel'), expected) + assert_almost_equal(p.reflectity_profile(q, 'MyModel'), expected) def test_sld_profile(self): p = Refnx() diff --git a/tests/calculators/refnx/test_refnx_wrapper.py b/tests/calculators/refnx/test_refnx_wrapper.py index f9d2a4cc..bb99d633 100644 --- a/tests/calculators/refnx/test_refnx_wrapper.py +++ b/tests/calculators/refnx/test_refnx_wrapper.py @@ -451,7 +451,7 @@ def test_calculate_github_test4_spline_resolution(self): p.add_item('Item3', 'MyModel') p.add_item('Item4', 'MyModel') p.update_model('MyModel', bkg=0) - sigma_to_fwhm = 2.355 + sigma_to_fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0)) p.set_resolution_function(LinearSpline(test4_dat[:, 0], sigma_to_fwhm * test4_dat[:, 3])) assert_allclose(p.calculate(test4_dat[:, 0], 'MyModel'), test4_dat[:, 1], rtol=0.03) diff --git a/tests/calculators/test_resolution_conventions.py b/tests/calculators/test_resolution_conventions.py new file mode 100644 index 00000000..5b7c7fb7 --- /dev/null +++ b/tests/calculators/test_resolution_conventions.py @@ -0,0 +1,207 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +"""Absolute checks on the width convention each wrapper hands to its backend. + +``ResolutionFunction.smearing()`` returns sigma for every resolution type; each +wrapper is then responsible for converting to what its backend expects: + +* refnx -- ``x_err`` is the **FWHM** at each q (a scalar ``x_err`` is instead a + constant dQ/Q FWHM *percentage*). +* refl1d -- ``QProbe.dQ`` is **sigma**. + +The cross-engine tests in ``tests/integration/test_cross_engine_resolution.py`` +only pin the engines against each other, so they cannot catch an error applied +consistently to both. These tests intercept the value at each engine boundary +and assert the exact numbers, which pins the convention absolutely. In +particular this is the only absolute check on the refl1d resolution path. + +See GitHub issue #367 for background. +""" + +import numpy as np +import pytest +from numpy.testing import assert_allclose +from refl1d import names +from refnx import reflect + +from easyreflectometry.calculators.refl1d.wrapper import Refl1dWrapper +from easyreflectometry.calculators.refnx.wrapper import RefnxWrapper +from easyreflectometry.model.resolution_functions import SIGMA_TO_FWHM +from easyreflectometry.model.resolution_functions import LinearSpline +from easyreflectometry.model.resolution_functions import PercentageFwhm +from easyreflectometry.model.resolution_functions import Pointwise + +Q = np.linspace(0.01, 0.3, 20) + +Q_KNOTS = np.linspace(0.001, 0.5, 10) +FWHM_KNOTS = 0.02 * Q_KNOTS + 0.001 + +QZ = np.linspace(0.001, 0.5, 50) +SIGMA_POINTS = 0.01 * QZ + 0.0005 +SQZ = SIGMA_POINTS**2 + + +def _build_refnx(): + wrapper = RefnxWrapper() + wrapper.reset_storage() + wrapper.create_material('Substrate') + wrapper.update_material('Substrate', real=2.07, imag=0.0) + wrapper.create_material('Film') + wrapper.update_material('Film', real=3.45, imag=0.0) + wrapper.create_layer('SubstrateLayer') + wrapper.assign_material_to_layer('Substrate', 'SubstrateLayer') + wrapper.create_layer('FilmLayer') + wrapper.assign_material_to_layer('Film', 'FilmLayer') + wrapper.update_layer('FilmLayer', thick=100.0, rough=3.0) + wrapper.create_item('Item') + wrapper.add_layer_to_item('FilmLayer', 'Item') + wrapper.add_layer_to_item('SubstrateLayer', 'Item') + wrapper.create_model('MyModel') + wrapper.add_item('Item', 'MyModel') + wrapper.update_model('MyModel', bkg=0.0) + return wrapper + + +def _build_refl1d(): + wrapper = Refl1dWrapper() + wrapper.reset_storage() + wrapper.create_material('Substrate') + wrapper.update_material('Substrate', rho=2.07, irho=0.0) + wrapper.create_material('Film') + wrapper.update_material('Film', rho=3.45, irho=0.0) + wrapper.create_layer('SubstrateLayer') + wrapper.assign_material_to_layer('Substrate', 'SubstrateLayer') + wrapper.create_layer('FilmLayer') + wrapper.assign_material_to_layer('Film', 'FilmLayer') + wrapper.update_layer('FilmLayer', thickness=100.0, interface=3.0) + wrapper.create_item('Item') + wrapper.add_layer_to_item('FilmLayer', 'Item') + wrapper.add_layer_to_item('SubstrateLayer', 'Item') + wrapper.create_model('MyModel') + wrapper.add_item('Item', 'MyModel') + wrapper.update_model('MyModel', bkg=0.0) + return wrapper + + +def _capture_refnx_x_err(monkeypatch, resolution_function): + """Run RefnxWrapper.calculate and return the x_err handed to refnx.""" + captured = {} + real_call = reflect.ReflectModel.__call__ + + def spy(self, x, p=None, x_err=None): + captured['x_err'] = x_err + return real_call(self, x, p=p, x_err=x_err) + + monkeypatch.setattr(reflect.ReflectModel, '__call__', spy) + + wrapper = _build_refnx() + wrapper.set_resolution_function(resolution_function) + wrapper.calculate(Q, 'MyModel') + return captured['x_err'] + + +def _capture_refl1d_dq(monkeypatch, resolution_function): + """Run Refl1dWrapper.calculate and return the dQ handed to refl1d's QProbe.""" + captured = {} + real_qprobe = names.QProbe + + def spy(**kwargs): + captured['dQ'] = np.asarray(kwargs['dQ'], dtype=float) + return real_qprobe(**kwargs) + + monkeypatch.setattr(names, 'QProbe', spy) + + wrapper = _build_refl1d() + wrapper.set_resolution_function(resolution_function) + wrapper.calculate(Q, 'MyModel') + return captured['dQ'] + + +# ----- the constant itself ----- + + +@pytest.mark.fast +def test_sigma_to_fwhm_is_the_gaussian_ratio(): + """Pin SIGMA_TO_FWHM against a literal. + + Every other test in this module imports SIGMA_TO_FWHM -- the same constant + the production code uses -- so a wrong value would cancel out on both sides + of the assertion and stay invisible. This is the one place the constant is + checked against an external fact: the FWHM/sigma ratio of a Gaussian, + 2*sqrt(2*ln2). + """ + assert SIGMA_TO_FWHM == pytest.approx(2.3548200450309493) + + +# ----- refnx expects FWHM ----- + + +@pytest.mark.fast +def test_refnx_receives_fwhm_for_linear_spline(monkeypatch): + x_err = _capture_refnx_x_err(monkeypatch, LinearSpline(Q_KNOTS, FWHM_KNOTS)) + + expected_fwhm = np.interp(Q, Q_KNOTS, FWHM_KNOTS) + assert_allclose(x_err, expected_fwhm) + + +@pytest.mark.fast +def test_refnx_receives_fwhm_for_pointwise(monkeypatch): + x_err = _capture_refnx_x_err(monkeypatch, Pointwise([QZ, np.ones_like(QZ), SQZ])) + + expected_sigma = np.interp(Q, QZ, np.sqrt(SQZ)) + assert_allclose(x_err, expected_sigma * SIGMA_TO_FWHM) + + +@pytest.mark.fast +def test_refnx_receives_scalar_percentage_for_percentage_fwhm(monkeypatch): + x_err = _capture_refnx_x_err(monkeypatch, PercentageFwhm(5.0)) + + # refnx reads a scalar x_err as a constant dQ/Q FWHM percentage, so the + # percentage is passed through verbatim -- not converted to a width. + assert np.isscalar(x_err) or np.ndim(x_err) == 0 + assert_allclose(x_err, 5.0) + + +# ----- refl1d expects sigma ----- + + +@pytest.mark.fast +def test_refl1d_receives_sigma_for_linear_spline(monkeypatch): + dq = _capture_refl1d_dq(monkeypatch, LinearSpline(Q_KNOTS, FWHM_KNOTS)) + + expected_fwhm = np.interp(Q, Q_KNOTS, FWHM_KNOTS) + assert_allclose(dq, expected_fwhm / SIGMA_TO_FWHM) + + +@pytest.mark.fast +def test_refl1d_receives_sigma_for_pointwise(monkeypatch): + dq = _capture_refl1d_dq(monkeypatch, Pointwise([QZ, np.ones_like(QZ), SQZ])) + + expected_sigma = np.interp(Q, QZ, np.sqrt(SQZ)) + assert_allclose(dq, expected_sigma) + + +@pytest.mark.fast +def test_refl1d_receives_sigma_for_percentage_fwhm(monkeypatch): + dq = _capture_refl1d_dq(monkeypatch, PercentageFwhm(5.0)) + + expected_sigma = (5.0 / 100.0) * Q / SIGMA_TO_FWHM + assert_allclose(dq, expected_sigma) + + +# ----- the two backends must receive widths that differ by exactly SIGMA_TO_FWHM ----- + + +@pytest.mark.fast +def test_engines_receive_widths_differing_by_sigma_to_fwhm(monkeypatch): + """The whole point of issue #367, stated directly. + + Catches a common-mode error that the cross-engine reflectivity comparison + cannot see: whatever the widths are, refnx's must be exactly SIGMA_TO_FWHM + times refl1d's. + """ + x_err = _capture_refnx_x_err(monkeypatch, LinearSpline(Q_KNOTS, FWHM_KNOTS)) + dq = _capture_refl1d_dq(monkeypatch, LinearSpline(Q_KNOTS, FWHM_KNOTS)) + + assert_allclose(x_err, dq * SIGMA_TO_FWHM) diff --git a/tests/integration/test_cross_engine_resolution.py b/tests/integration/test_cross_engine_resolution.py new file mode 100644 index 00000000..6da7be16 --- /dev/null +++ b/tests/integration/test_cross_engine_resolution.py @@ -0,0 +1,187 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +"""Cross-engine consistency checks for resolution function width conventions. + +The same model + resolution function should produce broadly the same +reflectivity on refnx and refl1d. A width-convention error at one engine +boundary shows up as a systematic disagreement between them. + +.. warning:: + + These are **smoke tests, not the regression tests for issue #367.** They + compare the engines against each other, so they are blind to any error + applied consistently to both, and -- measured, not assumed -- they are only + sensitive enough to catch *one* of the two bugs #367 fixed: + + * ``LinearSpline``: the pre-fix refl1d code **over**-smeared by 2.355x, + which moves the curve enough to be caught here (measured separation ~2x). + * ``Pointwise``: the pre-fix refnx code **under**-smeared by 2.355x from an + already-small width. That barely moves the curve -- measured separation + ~1.1x, against a baseline engine disagreement of the same size -- so **no + tolerance can catch it here.** The Pointwise test below is a consistency + check only. + + The actual, exact regression tests for both conventions live in + ``tests/calculators/test_resolution_conventions.py``, which intercepts the + widths handed to each backend and asserts them to floating-point precision. + Fix that file first if these ever conflict. + +.. note:: + + Reflectivity spans several decades and the engines' different resolution + algorithms (refnx: pointwise convolution; refl1d: oversampling) disagree + most at fringe minima, where R is tiny and *relative* differences explode. + The comparison is therefore made on ``log10(R)``, and the tolerances are + measured values with roughly 1.5x headroom rather than round numbers. + +See GitHub issue #367 for background. +""" + +import numpy as np +import pytest + +from easyreflectometry.calculators.refl1d.wrapper import Refl1dWrapper +from easyreflectometry.calculators.refnx.wrapper import RefnxWrapper +from easyreflectometry.model.resolution_functions import SIGMA_TO_FWHM +from easyreflectometry.model.resolution_functions import LinearSpline +from easyreflectometry.model.resolution_functions import PercentageFwhm +from easyreflectometry.model.resolution_functions import Pointwise + +Q = np.geomspace(0.005, 0.3, 100) + + +def _build_simple_model_refnx(wrapper): + """Build an ambient | 100 A film | substrate model on a refnx wrapper. + + The ambient layer is not optional decoration: both engines treat the first + layer as the semi-infinite superphase and ignore its thickness. Without it + the "film" becomes the ambient, leaving a bare interface with no Kiessig + fringes -- and resolution smearing acts almost entirely on fringes, so the + model would be insensitive to the very thing under test. + """ + wrapper.reset_storage() + wrapper.create_material('Ambient') + wrapper.update_material('Ambient', real=0.0, imag=0.0) + wrapper.create_material('Film') + wrapper.update_material('Film', real=3.45, imag=0.0) + wrapper.create_material('Substrate') + wrapper.update_material('Substrate', real=2.07, imag=0.0) + wrapper.create_layer('AmbientLayer') + wrapper.assign_material_to_layer('Ambient', 'AmbientLayer') + wrapper.create_layer('FilmLayer') + wrapper.assign_material_to_layer('Film', 'FilmLayer') + wrapper.update_layer('FilmLayer', thick=100.0, rough=3.0) + wrapper.create_layer('SubstrateLayer') + wrapper.assign_material_to_layer('Substrate', 'SubstrateLayer') + wrapper.update_layer('SubstrateLayer', rough=3.0) + wrapper.create_item('Item') + wrapper.add_layer_to_item('AmbientLayer', 'Item') + wrapper.add_layer_to_item('FilmLayer', 'Item') + wrapper.add_layer_to_item('SubstrateLayer', 'Item') + wrapper.create_model('MyModel') + wrapper.add_item('Item', 'MyModel') + wrapper.update_model('MyModel', bkg=0.0) + + +def _build_simple_model_refl1d(wrapper): + """Build the same ambient | 100 A film | substrate model on refl1d.""" + wrapper.reset_storage() + wrapper.create_material('Ambient') + wrapper.update_material('Ambient', rho=0.0, irho=0.0) + wrapper.create_material('Film') + wrapper.update_material('Film', rho=3.45, irho=0.0) + wrapper.create_material('Substrate') + wrapper.update_material('Substrate', rho=2.07, irho=0.0) + wrapper.create_layer('AmbientLayer') + wrapper.assign_material_to_layer('Ambient', 'AmbientLayer') + wrapper.create_layer('FilmLayer') + wrapper.assign_material_to_layer('Film', 'FilmLayer') + wrapper.update_layer('FilmLayer', thickness=100.0, interface=3.0) + wrapper.create_layer('SubstrateLayer') + wrapper.assign_material_to_layer('Substrate', 'SubstrateLayer') + wrapper.update_layer('SubstrateLayer', interface=3.0) + wrapper.create_item('Item') + wrapper.add_layer_to_item('AmbientLayer', 'Item') + wrapper.add_layer_to_item('FilmLayer', 'Item') + wrapper.add_layer_to_item('SubstrateLayer', 'Item') + wrapper.create_model('MyModel') + wrapper.add_item('Item', 'MyModel') + wrapper.update_model('MyModel', bkg=0.0) + + +def _both_engines(resolution_function): + """Return (refnx_reflectivity, refl1d_reflectivity) for one resolution.""" + refnx_w = RefnxWrapper() + _build_simple_model_refnx(refnx_w) + refnx_w.set_resolution_function(resolution_function) + refnx_r = refnx_w.calculate(Q, 'MyModel') + + refl1d_w = Refl1dWrapper() + _build_simple_model_refl1d(refl1d_w) + refl1d_w.set_resolution_function(resolution_function) + refl1d_r = refl1d_w.calculate(Q, 'MyModel') + + return refnx_r, refl1d_r + + +def _assert_log_close(refnx_r, refl1d_r, atol): + """Assert the engines agree to `atol` decades of R at every q.""" + deviation = np.abs(np.log10(refnx_r) - np.log10(refl1d_r)) + assert deviation.max() <= atol, ( + f'engines disagree by {deviation.max():.4f} decades ' + f'(factor {10 ** deviation.max():.2f}) at q={Q[np.argmax(deviation)]:.4f}, tolerance {atol}' + ) + + +@pytest.mark.fast +@pytest.mark.parametrize(('resolution_pct', 'atol'), [(1.0, 0.07), (5.0, 0.23), (10.0, 0.29)]) +def test_percentage_fwhm_consistent_across_engines(resolution_pct, atol): + """PercentageFwhm gives consistent results across engines. + + Measured disagreement grows with the width (0.041 / 0.149 / 0.191 decades + at 1% / 5% / 10% dQ/Q), so the tolerance is parametrized with it rather + than set to one blanket value. This combination was correct both before + and after issue #367; the test guards against regression. + """ + refnx_r, refl1d_r = _both_engines(PercentageFwhm(resolution_pct)) + _assert_log_close(refnx_r, refl1d_r, atol=atol) + + +@pytest.mark.fast +def test_linear_spline_consistent_across_engines(): + """LinearSpline gives consistent results across engines. + + This one does earn its keep: pre-fix, refl1d read the FWHM knots as sigma + and over-smeared by 2.355x. Measured max |dlog10(R)|: 0.085 with the fix, + 0.182 without it, so atol=0.13 separates them with ~1.5x headroom either + way. + """ + q_knots = np.linspace(0.001, 0.5, 10) + fwhm_knots = 0.02 * q_knots + 0.001 + + refnx_r, refl1d_r = _both_engines(LinearSpline(q_knots, fwhm_knots)) + _assert_log_close(refnx_r, refl1d_r, atol=0.13) + + +@pytest.mark.fast +def test_pointwise_consistent_across_engines(): + """Pointwise (sigma from sQz) is consistent across engines. + + Consistency check only. Pre-fix, refnx under-smeared these widths by + 2.355x, but measured max |dlog10(R)| is 0.092 pre-fix versus 0.085 with + the fix -- indistinguishable, because under-smearing an already-small + width barely moves the curve. Do not add a tolerance here expecting it to + catch that bug; ``tests/calculators/test_resolution_conventions.py`` is + what actually pins it. + + The sQz values mirror the LinearSpline knots, so the applied smearing -- + and hence the measured agreement -- matches that test. + """ + qz = np.linspace(0.001, 0.5, 50) + r = np.ones_like(qz) # only kept for serialization round-trips + sigma = (0.02 * qz + 0.001) / SIGMA_TO_FWHM + sqz = sigma**2 + + refnx_r, refl1d_r = _both_engines(Pointwise([qz, r, sqz])) + _assert_log_close(refnx_r, refl1d_r, atol=0.13) diff --git a/tests/model/test_model.py b/tests/model/test_model.py index 0c83d5dc..a2dd46ea 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -45,8 +45,9 @@ def test_default(self): assert_equal(p.background.min, 0.0) assert_equal(p.background.max, np.inf) assert_equal(p.background.fixed, True) - assert p._resolution_function.smearing([1]) == 5.0 - assert p._resolution_function.smearing([100]) == 5.0 + sigma_to_fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0)) + assert np.allclose(p._resolution_function.smearing([1]), 5.0 / 100.0 * 1.0 / sigma_to_fwhm) + assert np.allclose(p._resolution_function.smearing([100]), 5.0 / 100.0 * 100.0 / sigma_to_fwhm) def test_from_pars(self): m1 = Material(6.908, -0.278, 'Boron') @@ -81,8 +82,9 @@ def test_from_pars(self): assert_equal(mod.background.min, 0.0) assert_equal(mod.background.max, np.inf) assert_equal(mod.background.fixed, True) - assert mod._resolution_function.smearing([1]) == 2.0 - assert mod._resolution_function.smearing([100]) == 2.0 + sigma_to_fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0)) + assert np.allclose(mod._resolution_function.smearing([1]), 2.0 / 100.0 * 1.0 / sigma_to_fwhm) + assert np.allclose(mod._resolution_function.smearing([100]), 2.0 / 100.0 * 100.0 / sigma_to_fwhm) def test_add_assemblies(self): m1 = Material(6.908, -0.278, 'Boron') @@ -427,8 +429,8 @@ def test_dict_round_trip(interface): if interface is not None: assert model.interface().name == model_from_dict.interface().name assert_almost_equal( - model.interface().reflectivity_profile([0.3], model.unique_name), - model_from_dict.interface().reflectivity_profile([0.3], model_from_dict.unique_name), + model.interface().reflectity_profile([0.3], model.unique_name), + model_from_dict.interface().reflectity_profile([0.3], model_from_dict.unique_name), ) @@ -525,7 +527,8 @@ def test_round_trip_preserves_resolution_function(self): d = model.as_dict() global_object.map._clear() restored = Model.from_dict(d) - assert restored._resolution_function.smearing(100) == 3.0 + sigma_to_fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0)) + assert np.allclose(restored._resolution_function.smearing(100), 3.0 / 100.0 * 100.0 / sigma_to_fwhm) def test_round_trip_preserves_interface(self): global_object.map._clear() diff --git a/tests/model/test_resolution_functions.py b/tests/model/test_resolution_functions.py index 1391949b..480ca2c6 100644 --- a/tests/model/test_resolution_functions.py +++ b/tests/model/test_resolution_functions.py @@ -6,6 +6,7 @@ import numpy as np from easyreflectometry.model.resolution_functions import DEFAULT_RESOLUTION_FWHM_PERCENTAGE +from easyreflectometry.model.resolution_functions import SIGMA_TO_FWHM from easyreflectometry.model.resolution_functions import LinearSpline from easyreflectometry.model.resolution_functions import PercentageFwhm from easyreflectometry.model.resolution_functions import Pointwise @@ -17,28 +18,31 @@ def test_constructor(self): # When resolution_function = PercentageFwhm(1.0) - # Then Expect - assert np.all(resolution_function.smearing([0, 2.5]) == np.array([1.0, 1.0])) - assert resolution_function.smearing([-100]) == np.array([1.0]) - assert resolution_function.smearing([100]) == np.array([1.0]) + # Then Expect: smearing() returns sigma = (constant / 100) * q / SIGMA_TO_FWHM + # Negative q is not asserted: sigma scales with q here, so q < 0 yields a + # negative width, which is meaningless. Leaving it unpinned keeps the door + # open to guarding with abs(q) without failing this test. + expected = (1.0 / 100.0) * np.array([0.0, 2.5]) / SIGMA_TO_FWHM + assert np.allclose(resolution_function.smearing([0, 2.5]), expected) + assert np.allclose(resolution_function.smearing([100]), (1.0 / 100.0) * 100.0 / SIGMA_TO_FWHM) def test_constructor_none(self): # When resolution_function = PercentageFwhm() - # Then Expect - assert np.all( - resolution_function.smearing([0, 2.5]) == [DEFAULT_RESOLUTION_FWHM_PERCENTAGE, DEFAULT_RESOLUTION_FWHM_PERCENTAGE] - ) - assert resolution_function.smearing([-100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE - assert resolution_function.smearing([100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE + # Then Expect: defaults to DEFAULT_RESOLUTION_FWHM_PERCENTAGE, returned as sigma + # Negative q is not asserted -- see test_constructor. + c = DEFAULT_RESOLUTION_FWHM_PERCENTAGE + expected = (c / 100.0) * np.array([0.0, 2.5]) / SIGMA_TO_FWHM + assert np.allclose(resolution_function.smearing([0, 2.5]), expected) + assert np.allclose(resolution_function.smearing([100]), (c / 100.0) * 100.0 / SIGMA_TO_FWHM) def test_as_dict(self): # When resolution_function = PercentageFwhm(1.0) # Then Expect - assert resolution_function.as_dict() == {'smearing': 'PercentageFwhm', 'constant': 1.0} + resolution_function.as_dict() == {'smearing': 'PercentageFwhm', 'constant': 1.0} def test_dict_round_trip(self): # When @@ -57,17 +61,19 @@ def test_constructor(self): # When resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) - # Then Expect - assert np.all(resolution_function.smearing([0, 2.5]) == np.array([5, 6.25])) - assert resolution_function.smearing([-100]) == np.array([5.0]) - assert resolution_function.smearing([100]) == np.array([10.0]) + # Then Expect: smearing() returns sigma (FWHM knots converted to sigma) + # Unlike PercentageFwhm, q outside the knot range is meaningful here: + # np.interp clamps to the end knots, so the width stays positive. + assert np.allclose(resolution_function.smearing([0, 2.5]), np.array([5, 6.25]) / SIGMA_TO_FWHM) + assert np.allclose(resolution_function.smearing([-100]), np.array([5.0]) / SIGMA_TO_FWHM) + assert np.allclose(resolution_function.smearing([100]), np.array([10.0]) / SIGMA_TO_FWHM) def test_as_dict(self): # When resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) # Then Expect - assert resolution_function.as_dict() == { + resolution_function.as_dict() == { 'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10], @@ -117,12 +123,7 @@ def test_as_dict(self): resolution_function = Pointwise(q_data_points=self.data_points) # Then Expect - assert resolution_function.as_dict() == { - 'smearing': 'Pointwise', - 'q_data_points': self.data_points[0], - 'R_data_points': self.data_points[1], - 'sQz_data_points': self.data_points[2], - } + assert resolution_function.as_dict(), {'smearing': 'Pointwise', 'q_data_points': [0, 10]} def test_dict_round_trip(self): # When diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index 7fe04009..0d466be7 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -27,8 +27,8 @@ def test_default(self): assert p.roughness.value == 3.3 assert str(p.roughness.unit) == 'Å' assert p.roughness.fixed is True - assert_almost_equal(p.material.sld.value, 2.268770124481328) - assert_almost_equal(p.material.isld.value, 0) + assert_almost_equal(p.material.sld, 2.268770124481328) + assert_almost_equal(p.material.isld, 0) assert p.material.name == 'C10H18NO8P in D2O' assert p.solvent.sld.value == 6.36 assert p.solvent.isld.value == 0 @@ -69,7 +69,7 @@ def test_from_pars_constraint(self): ) assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld.value, 0.31494833333333333) + assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 @@ -77,10 +77,10 @@ def test_from_pars_constraint(self): assert p.solvent_fraction.value == 0.5 p.area_per_molecule = 30 assert p.area_per_molecule.value == 30 - assert_almost_equal(p.material.sld.value, 0.7119138888888887) + assert_almost_equal(p.material.sld, 0.7119138888888887) p.thickness.value = 10 assert p.thickness.value == 10 - assert_almost_equal(p.material.sld.value, 0.9103966666666665) + assert_almost_equal(p.material.sld, 0.9103966666666665) @unittest.skip('Instantiation of LayerAreaPerMolecule fails, despite working everywhere else.') def test_solvent_change(self): @@ -97,7 +97,7 @@ def test_solvent_change(self): assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 print(p.material) - assert_almost_equal(p.material.sld.value, 0.31494833333333333) + assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 @@ -107,7 +107,7 @@ def test_solvent_change(self): p.solvent = d2o assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld.value, 3.762948333333333) + assert_almost_equal(p.material.sld, 3.762948333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == 6.335 @@ -127,7 +127,7 @@ def test_molecular_formula_change(self): ) assert p.molecular_formula == 'C8O10H12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld.value, 0.31494833333333333) + assert_almost_equal(p.material.sld, 0.31494833333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 @@ -138,7 +138,7 @@ def test_molecular_formula_change(self): p.molecular_formula = 'C8O10D12P' assert p.molecular_formula == 'C8O10D12P' assert p.area_per_molecule.value == 50 - assert_almost_equal(p.material.sld.value, 1.3558483333333333) + assert_almost_equal(p.material.sld, 1.3558483333333333) assert p.thickness.value == 12 assert p.roughness.value == 2 assert p.solvent.sld.value == -0.561 diff --git a/tests/sample/elements/materials/test_material_mixture.py b/tests/sample/elements/materials/test_material_mixture.py index d3912b7d..3c2a3f65 100644 --- a/tests/sample/elements/materials/test_material_mixture.py +++ b/tests/sample/elements/materials/test_material_mixture.py @@ -15,8 +15,8 @@ def test_default(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.186) - assert_almost_equal(material_mixture.isld.value, 0) + assert_almost_equal(material_mixture.sld, 4.186) + assert_almost_equal(material_mixture.isld, 0) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -24,12 +24,12 @@ def test_default_constraint(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.186) - assert_almost_equal(material_mixture.isld.value, 0) + assert_almost_equal(material_mixture.sld, 4.186) + assert_almost_equal(material_mixture.isld, 0) material_mixture.material_a.sld.value = 0 material_mixture.material_b.isld.value = -1 - assert_almost_equal(material_mixture.sld.value, 2.093) - assert_almost_equal(material_mixture.isld.value, -0.5) + assert_almost_equal(material_mixture.sld, 2.093) + assert_almost_equal(material_mixture.isld, -0.5) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -38,59 +38,59 @@ def test_fraction_constraint(self): q = Material(6.908, -0.278, 'Boron') material_mixture = MaterialMixture(p, q, 0.2) assert material_mixture.fraction.value == 0.2 - assert_almost_equal(material_mixture.sld.value, 4.7304) - assert_almost_equal(material_mixture.isld.value, -0.0556) + assert_almost_equal(material_mixture.sld, 4.7304) + assert_almost_equal(material_mixture.isld, -0.0556) material_mixture._fraction.value = 0.5 assert material_mixture.fraction.value == 0.5 - assert_almost_equal(material_mixture.sld.value, 5.54700) - assert_almost_equal(material_mixture.isld.value, -0.1390) + assert_almost_equal(material_mixture.sld, 5.54700) + assert_almost_equal(material_mixture.isld, -0.1390) def test_material_a_change(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.186) - assert_almost_equal(material_mixture.isld.value, 0) + assert_almost_equal(material_mixture.sld, 4.186) + assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_a = q assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 5.54700) - assert_almost_equal(material_mixture.isld.value, -0.1390) + assert_almost_equal(material_mixture.sld, 5.54700) + assert_almost_equal(material_mixture.isld, -0.1390) def test_material_b_change(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.186) - assert_almost_equal(material_mixture.isld.value, 0) + assert_almost_equal(material_mixture.sld, 4.186) + assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 5.54700) - assert_almost_equal(material_mixture.isld.value, -0.1390) + assert_almost_equal(material_mixture.sld, 5.54700) + assert_almost_equal(material_mixture.isld, -0.1390) def test_material_b_change_double(self) -> None: material_mixture = MaterialMixture() assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.186) - assert_almost_equal(material_mixture.isld.value, 0) + assert_almost_equal(material_mixture.sld, 4.186) + assert_almost_equal(material_mixture.isld, 0) q = Material(6.908, -0.278, 'Boron') material_mixture.material_b = q assert material_mixture.name == 'EasyMaterial/Boron' assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 5.54700) - assert_almost_equal(material_mixture.isld.value, -0.1390) + assert_almost_equal(material_mixture.sld, 5.54700) + assert_almost_equal(material_mixture.isld, -0.1390) r = Material(0.00, 0.00, 'ACMW') material_mixture.material_b = r assert material_mixture.name == 'EasyMaterial/ACMW' assert material_mixture.fraction.value == 0.5 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 2.0930) - assert_almost_equal(material_mixture.isld.value, 0.0000) + assert_almost_equal(material_mixture.sld, 2.0930) + assert_almost_equal(material_mixture.isld, 0.0000) def test_from_pars(self): p = Material() @@ -98,8 +98,8 @@ def test_from_pars(self): material_mixture = MaterialMixture(p, q, 0.2) assert material_mixture.fraction.value == 0.2 assert str(material_mixture._fraction.unit) == 'dimensionless' - assert_almost_equal(material_mixture.sld.value, 4.7304) - assert_almost_equal(material_mixture.isld.value, -0.0556) + assert_almost_equal(material_mixture.sld, 4.7304) + assert_almost_equal(material_mixture.isld, -0.0556) assert str(material_mixture._sld.unit) == '1/Å^2' assert str(material_mixture._isld.unit) == '1/Å^2' @@ -158,7 +158,7 @@ def test_calculator_binding_uses_mixed_sld(self) -> None: mixture = MaterialMixture(material_a, material_b, fraction=0.25, interface=interface) # 2 * 0.75 + 6 * 0.25 = 1.5 + 1.5 = 3.0 - assert_almost_equal(mixture.sld.value, 3.0) + assert_almost_equal(mixture.sld, 3.0) wrapper_material = interface()._wrapper.storage['material'][mixture.unique_name] assert_almost_equal(wrapper_material.real.value, 3.0) assert_almost_equal(wrapper_material.imag.value, 0.0) @@ -173,8 +173,8 @@ def test_mutation_propagates_after_round_trip(self) -> None: global_object.map._clear() q = MaterialMixture.from_dict(p_dict) - assert_almost_equal(q.sld.value, 3.0) + assert_almost_equal(q.sld, 3.0) q.fraction = 0.8 # 2 * 0.2 + 6 * 0.8 = 0.4 + 4.8 = 5.2 - assert_almost_equal(q.sld.value, 5.2) + assert_almost_equal(q.sld, 5.2) diff --git a/tests/summary/test_summary.py b/tests/summary/test_summary.py index 271de2c4..a636b504 100644 --- a/tests/summary/test_summary.py +++ b/tests/summary/test_summary.py @@ -4,7 +4,6 @@ import os from unittest.mock import MagicMock -import numpy as np import pytest from easyscience import global_object @@ -137,7 +136,7 @@ def test_experiments_section(self, project: Project) -> None: assert 'No. of data points' in html assert '408' in html assert 'Resolution function' in html - assert 'PercentageFwhm' in html + assert 'Pointwise' in html def test_experiments_section_percentage_fhwm(self, project: Project) -> None: # When @@ -168,51 +167,6 @@ def test_refinement_section(self, project: Project) -> None: assert 'No. of free parameters:' in html assert '0' in html assert 'No. of constraints' in html - # The (previously misspelt) constraints token must be fully substituted. - assert 'num_constriants' not in html - assert 'num_constraints' not in html - - @staticmethod - def _populate_fit_results(project: Project, chi2: float, n_points: int, n_pars: int) -> None: - """Emulate a completed fit by storing results on the project's fitter.""" - fit_result = MagicMock() - fit_result.chi2 = chi2 - fit_result.x = np.arange(n_points) - fit_result.n_pars = n_pars - project.fitter._fit_results = [fit_result] - - def test_compute_goodness_of_fit_na_before_fit(self, project: Project) -> None: - # When - summary = Summary(project) - - # Then Expect: no fit has been run, so goodness-of-fit is unavailable. - assert summary._compute_goodness_of_fit() == 'N/A' - - def test_compute_goodness_of_fit_after_fit(self, project: Project) -> None: - # When: reduced chi² = 20 / (14 - 4) = 2.0 - summary = Summary(project) - self._populate_fit_results(project, chi2=20.0, n_points=14, n_pars=4) - - # Then - gof = summary._compute_goodness_of_fit() - - # Expect - assert gof != 'N/A' - assert float(gof) == pytest.approx(2.0) - - def test_refinement_section_shows_goodness_of_fit(self, project: Project) -> None: - # When - summary = Summary(project) - self._populate_fit_results(project, chi2=20.0, n_points=14, n_pars=4) - gof = summary._compute_goodness_of_fit() - - # Then - html = summary._refinement_section() - - # Expect: the template token is replaced with the actual value, not 'N/A'. - assert gof != 'N/A' - assert gof in html - assert 'goodness_of_fit' not in html def test_save_sld_plot(self, project: Project, tmp_path) -> None: # When diff --git a/tests/test_fitting.py b/tests/test_fitting.py index 896de593..9fd02a4b 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -4,6 +4,7 @@ import os from unittest.mock import MagicMock +from unittest.mock import patch import numpy as np import pytest @@ -287,46 +288,6 @@ def test_reduced_chi_uses_global_dof_across_fit_results(): assert fitter.reduced_chi == pytest.approx(expected) -def test_record_fit_results_populates_reduced_chi(): - """Results computed outside the fitter can be recorded so reduced_chi works. - - Mirrors the app path where the threaded fit runs on the low-level - easy_science_multi_fitter and the high-level results must be recorded - explicitly (otherwise the HTML summary goodness-of-fit shows 'N/A'). - """ - model = Model() - model.interface = CalculatorFactory() - fitter = MultiFitter(model) - - assert fitter.reduced_chi is None - - fit_result = MagicMock() - fit_result.chi2 = 20.0 - fit_result.x = np.arange(14) - fit_result.n_pars = 4 - - fitter.record_fit_results([fit_result]) - - assert fitter.reduced_chi == pytest.approx(20.0 / (14 - 4)) - - -def test_record_fit_results_none_clears_state(): - model = Model() - model.interface = CalculatorFactory() - fitter = MultiFitter(model) - - fit_result = MagicMock() - fit_result.chi2 = 20.0 - fit_result.x = np.arange(14) - fit_result.n_pars = 4 - fitter.record_fit_results([fit_result]) - - fitter.record_fit_results(None) - - assert fitter.reduced_chi is None - assert fitter.chi2 is None - - def test_fit_single_data_set_1d_all_zero_variance_raises(): """Legacy mask mode raises when all points have zero variance.""" model = Model() @@ -848,6 +809,44 @@ def _fake_fit(*, x, y, weights): # --------------------------------------------------------------------------- +def _fake_sampling_results(draws=None, param_names=None, state=None, logp=None): + """Build a stand-in for the core ``SamplingResults`` returned by ``Sampler.sample``.""" + res = MagicMock() + res.draws = np.ones((10, 2)) if draws is None else draws + res.param_names = ['a', 'b'] if param_names is None else param_names + res.state = state + res.logp = logp + return res + + +def _patch_sampler(capture, results=None): + """Patch ``easyreflectometry.fitting.Sampler`` and capture its call args. + + Records the constructor's ``(x, y, weights)`` and the ``sample()`` + hyperparameters into the ``capture`` dict, and returns ``results`` (a + fake ``SamplingResults``) from ``sample()``. + """ + results = results if results is not None else _fake_sampling_results() + + def _ctor(fitter, *, x, y, weights, **kwargs): + capture['fitter'] = fitter + capture['x'] = x + capture['y'] = y + capture['weights'] = weights + capture.update(kwargs) # e.g. sampler_kwargs if passed to the ctor + instance = MagicMock() + + def _sample(**sample_kwargs): + capture.update(sample_kwargs) + return results + + instance.sample = MagicMock(side_effect=_sample) + capture['instance'] = instance + return instance + + return patch('easyreflectometry.fitting.Sampler', side_effect=_ctor) + + class TestMCMCSampleRequiresBumpsEngine: """mcmc_sample() must raise when the core engine is not a BUMPS instance.""" @@ -864,138 +863,129 @@ def test_raises_runtime_error_when_not_bumps(self): with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): fitter.mcmc_sample(data) - def test_wrapper_check_runs_before_core_mcmc_sample(self): - """The wrapper-level guard must fire before delegating to the core sampler. + def test_wrapper_check_runs_before_sampler(self): + """The wrapper-level guard must fire before constructing the core ``Sampler``. - Replace the core ``mcmc_sample`` with a sentinel that would record any call; - the guard should raise without invoking it. + Patch ``Sampler`` with a sentinel that would record any instantiation; + the guard should raise without ever building it. """ model = Model() model.interface = CalculatorFactory() fitter = MultiFitter(model) # default minimizer is LMFit, not BUMPS - core_called = {'count': 0} - - def _should_not_be_called(**_kwargs): - core_called['count'] += 1 - return {'draws': np.empty((0, 0)), 'param_names': [], 'state': None, 'logp': None} - - fitter.easy_science_multi_fitter.mcmc_sample = _should_not_be_called + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): - fitter.mcmc_sample(data) - assert core_called['count'] == 0 + with _patch_sampler(capture) as sampler_cls: + with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): + fitter.mcmc_sample(data) + sampler_cls.assert_not_called() class TestMCMCSampleBasic: """Basic mcmc_sample() dispatch and return-value forwarding.""" - def test_returns_core_result_dict(self): - """mcmc_sample() returns whatever the core MultiFitter.mcmc_sample() returns.""" + def test_returns_result_dict_from_sampler(self): + """mcmc_sample() returns a dict built from the core Sampler's SamplingResults.""" model = Model() model.interface = CalculatorFactory() fitter = MultiFitter(model) - # Mock the core MultiFitter.mcmc_sample to return a known dict - fake_result = {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(return_value=fake_result) + + draws = np.ones((10, 2)) + sentinel_state = object() + logp = np.zeros(10) + results = _fake_sampling_results(draws=draws, param_names=['a', 'b'], state=sentinel_state, logp=logp) + + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - result = fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=5) - assert result is fake_result + with _patch_sampler(capture, results=results): + result = fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=5) + + # The fitter passed to Sampler is the core MultiFitter + assert capture['fitter'] is fitter.easy_science_multi_fitter + assert result['draws'] is draws + assert result['param_names'] == ['a', 'b'] + assert result['state'] is sentinel_state + assert result['logp'] is logp - def test_forwards_hyperparams_to_core(self): - """Samples, burn, thin, population, chains are forwarded to core.""" + def test_forwards_hyperparams_to_sampler(self): + """Samples, burn, thin, population are forwarded to Sampler.sample().""" model = Model() model.interface = CalculatorFactory() fitter = MultiFitter(model) - captured = {} - - def _fake_mcmc_sample(*, x, y, weights, samples, burn, thin, population, **kwargs): - captured['samples'] = samples - captured['burn'] = burn - captured['thin'] = thin - captured['population'] = population - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} - fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - fitter.mcmc_sample(data, samples=500, burn=100, thin=5, population=8) - assert captured['samples'] == 500 - assert captured['burn'] == 100 - assert captured['thin'] == 5 - assert captured['population'] == 8 + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=500, burn=100, thin=5, population=8) + assert capture['samples'] == 500 + assert capture['burn'] == 100 + assert capture['thin'] == 5 + assert capture['population'] == 8 - def test_forwards_population_to_core(self): - """'population' argument is forwarded to core.""" + def test_forwards_population_to_sampler(self): + """'population' argument is forwarded to Sampler.sample().""" model = Model() model.interface = CalculatorFactory() fitter = MultiFitter(model) - captured = {} - - def _fake_mcmc_sample(*, x, y, weights, population, **kwargs): - captured['population'] = population - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} - fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=6) - assert captured['population'] == 6 + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=6) + assert capture['population'] == 6 class TestMCMCSampleInitializer: """initializer parameter is forwarded via sampler_kwargs.""" def test_initializer_passed_as_sampler_kwargs_init(self): - """initializer='lhs' should be passed as sampler_kwargs={'init': 'lhs'} to core.""" + """initializer='lhs' should be passed as sampler_kwargs={'init': 'lhs'} to Sampler.sample().""" model = Model() model.interface = CalculatorFactory() fitter = MultiFitter(model) - captured = {} - - def _fake_mcmc_sample(*, sampler_kwargs, **kwargs): - captured['sampler_kwargs'] = sampler_kwargs - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} - fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - fitter.mcmc_sample(data, samples=100, burn=20, thin=2, initializer='lhs') - assert captured['sampler_kwargs'] == {'init': 'lhs'} + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, initializer='lhs') + assert capture['sampler_kwargs'] == {'init': 'lhs'} def test_initializer_none_omits_sampler_kwargs(self): """When initializer is None, sampler_kwargs should be None, not an empty dict.""" @@ -1003,23 +993,19 @@ def test_initializer_none_omits_sampler_kwargs(self): model.interface = CalculatorFactory() fitter = MultiFitter(model) - captured = {} - - def _fake_mcmc_sample(*, sampler_kwargs, **kwargs): - captured['sampler_kwargs'] = sampler_kwargs - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} - fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) + + capture = {} data = sc.DataGroup({ 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, 10))}, 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(10), variances=np.ones(10) * 0.01)}, }) - fitter.mcmc_sample(data, samples=100, burn=20, thin=2) - assert captured['sampler_kwargs'] is None + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + assert capture['sampler_kwargs'] is None class TestMCMCSampleZeroVariance: @@ -1034,17 +1020,10 @@ def test_hybrid_transforms_zero_variance_points(self): # Use legacy_mask so zero-variance points are dropped fitter = MultiFitter(model, objective='legacy_mask') - captured = {} - - def _fake_mcmc_sample(*, x, y, weights, **kwargs): - captured['x'] = x - captured['y'] = y - captured['weights'] = weights - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + capture = {} fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) qz = np.linspace(0.01, 0.3, 10) r = np.exp(-qz * 50) @@ -1058,12 +1037,13 @@ def _fake_mcmc_sample(*, x, y, weights, **kwargs): with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') - fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) # legacy_mask should drop the 2 zero-variance points - assert len(captured['x'][0]) == 8 - assert len(captured['y'][0]) == 8 - assert len(captured['weights'][0]) == 8 + assert len(capture['x'][0]) == 8 + assert len(capture['y'][0]) == 8 + assert len(capture['weights'][0]) == 8 mask_warnings = [str(ww.message) for ww in w if 'Masked' in str(ww.message)] assert len(mask_warnings) == 1 @@ -1077,16 +1057,10 @@ def test_per_call_objective_override(self): model.interface = CalculatorFactory() fitter = MultiFitter(model, objective='legacy_mask') # default - captured = {} - - def _fake_mcmc_sample(*, x, y, weights, **kwargs): - captured['x'] = x - captured['y'] = y - return {'draws': np.ones((10, 2)), 'param_names': ['a', 'b'], 'state': None, 'logp': None} + capture = {} fitter.easy_science_multi_fitter = MagicMock() fitter.easy_science_multi_fitter.minimizer.package = 'bumps' - fitter.easy_science_multi_fitter.mcmc_sample = MagicMock(side_effect=_fake_mcmc_sample) qz = np.linspace(0.01, 0.3, 10) r = np.exp(-qz * 50) @@ -1101,6 +1075,194 @@ def _fake_mcmc_sample(*, x, y, weights, **kwargs): # Override to hybrid — should keep all 10 points with warnings.catch_warnings(record=True): warnings.simplefilter('always') - fitter.mcmc_sample(data, samples=100, burn=20, thin=2, objective='hybrid') + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, objective='hybrid') + + assert len(capture['x'][0]) == 10 # all points kept (Mighell-substituted) + + +class TestMCMCSampleMighellWarningsAndZeroVarianceGuard: + """mcmc_sample() must warn about Mighell-transformed points feeding the + Bayesian likelihood, and refuse data with no uncertainties at all.""" + + @staticmethod + def _make_fitter(objective='hybrid'): + model = Model() + model.interface = CalculatorFactory() + fitter = MultiFitter(model, objective=objective) + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + return fitter + + @staticmethod + def _make_data(variances): + qz = np.linspace(0.01, 0.3, 10) + r = np.exp(-qz * 50) + return sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=qz)}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=r, variances=variances)}, + }) + + def test_hybrid_partial_zero_variance_warns_mighell_substitution(self): + fitter = self._make_fitter() + variances = np.ones(10) * 0.01 + variances[3:5] = 0.0 + data = self._make_data(variances) + + capture = {} + with pytest.warns( + UserWarning, + match=r'Mighell substitution to 2 zero-variance point\(s\) in reflectivity 0 during sampling', + ): + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + + assert len(capture['x'][0]) == 10 + + def test_mighell_objective_warns_transform_all_points(self): + fitter = self._make_fitter(objective='mighell') + data = self._make_data(np.ones(10) * 0.01) + + capture = {} + with pytest.warns( + UserWarning, + match=r'Applied Mighell transform to all 10 point\(s\) in reflectivity 0 during sampling', + ): + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + + assert len(capture['x'][0]) == 10 + + def test_all_zero_variance_hybrid_raises(self): + fitter = self._make_fitter() + data = self._make_data(np.zeros(10)) + + capture = {} + with _patch_sampler(capture) as sampler_cls: + with pytest.raises(ValueError, match='all points have zero variance'): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + sampler_cls.assert_not_called() + + def test_all_zero_variance_legacy_mask_raises(self): + fitter = self._make_fitter(objective='legacy_mask') + data = self._make_data(np.zeros(10)) + + capture = {} + with _patch_sampler(capture) as sampler_cls: + with pytest.raises(ValueError, match='all points have zero variance'): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + sampler_cls.assert_not_called() + + def test_all_zero_variance_allowed_with_explicit_mighell(self): + """Explicitly opting in to objective='mighell' keeps working on + variance-free (e.g. raw count) data, with a warning.""" + fitter = self._make_fitter(objective='mighell') + data = self._make_data(np.zeros(10)) + + capture = {} + with pytest.warns(UserWarning, match='not a true likelihood'): + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + + assert len(capture['x'][0]) == 10 + + +# --------------------------------------------------------------------------- +# Analytic weighted-least-squares convention test (issue #370) +# --------------------------------------------------------------------------- + + +def _analytic_wls(design, y, point_weights): + """Solve min_beta sum_i (point_weights_i * (y_i - design_i . beta))^2. + + Returns the solution and the unscaled covariance (X^T W X)^-1 of the + corresponding weighted least-squares problem. + """ + a = design * point_weights[:, None] + b = y * point_weights + beta, *_ = np.linalg.lstsq(a, b, rcond=None) + covariance = np.linalg.inv(a.T @ a) + return beta, covariance + + +@pytest.mark.parametrize('minimizer', [AvailableMinimizers.LMFit, AvailableMinimizers.Bumps]) +def test_fit_weight_convention_matches_analytic_wls(minimizer): + """Pin the weights = 1/sigma convention end-to-end against analytic WLS. + + A reflectometry model is exactly linear in (scale, background): + R(q) = scale * f(q) + background, so weighted least squares has the + closed-form solution beta = (X^T W X)^-1 X^T W y with W = diag(1/sigma^2). + On heteroscedastic data the candidate weight conventions (1/sigma, sigma, + 1/sigma^2) give measurably different solutions, so this test fails if the + convention between ``_prepare_fit_arrays`` and the EasyScience core + minimizers ever drifts. See issue #370. + """ + construction_background = 1e-7 + si = Material(2.07, 0, 'Si') + sio2 = Material(3.47, 0, 'SiO2') + d2o = Material(6.36, 0, 'D2O') + sample = Sample( + Multilayer(Layer(si, 0, 0, 'Si layer')), + Multilayer(Layer(sio2, 30, 3, 'SiO2 layer')), + Multilayer(Layer(d2o, 0, 3, 'D2O Subphase')), + name='WLS Structure', + ) + model = Model(sample, 1.0, construction_background, PercentageFwhm(0.02), 'WLS Model') + model.interface = CalculatorFactory() + fitter = MultiFitter(model) + fitter.easy_science_multi_fitter.switch_minimizer(minimizer) + + # Unit-scale, zero-background reflectivity curve of the fixed structure + q = np.linspace(0.01, 0.25, 30) + f = fitter._fit_func[0](q) - construction_background + assert np.all(f > 0) + + # Deterministic heteroscedastic data that does NOT lie on the model + scale_true, background_true = 1.3, 4.0e-6 + signal = scale_true * f + background_true + fractional_error = 0.03 + 0.02 * np.cos(40.0 * q) ** 2 + sigma = fractional_error * signal + perturbation = 0.8 * np.cos(7.0 * np.arange(q.size) + 0.3) + y = signal + perturbation * sigma + variances = sigma**2 + + design = np.column_stack([f, np.ones_like(f)]) + beta, covariance = _analytic_wls(design, y, 1.0 / sigma) + beta_if_sigma, _ = _analytic_wls(design, y, sigma) + beta_if_inverse_variance, _ = _analytic_wls(design, y, 1.0 / sigma**2) + + # Sanity check: the conventions are distinguishable well beyond the fit tolerance + scale_tolerance = 1e-3 + background_tolerance = 5e-8 + scale_margin = min(abs(beta_if_sigma[0] - beta[0]), abs(beta_if_inverse_variance[0] - beta[0])) + assert scale_margin > 10 * scale_tolerance, 'test data cannot discriminate weight conventions' + + model.scale.fixed = False + model.scale.bounds = (0.5, 3.0) + model.scale.value = 1.0 + model.background.fixed = False + model.background.bounds = (1e-9, 1e-4) + model.background.value = 1e-6 + + data = DataSet1D( + name='wls_convention', + x=q, + y=y, + ye=variances, + model=model, + auto_background=False, + ) + result = fitter.fit_single_data_set_1d(data) - assert len(captured['x'][0]) == 10 # all points kept (Mighell-substituted) + assert result.success + assert model.scale.value == pytest.approx(beta[0], abs=scale_tolerance) + assert model.background.value == pytest.approx(beta[1], abs=background_tolerance) + + if minimizer == AvailableMinimizers.LMFit: + # lmfit scales the covariance by reduced chi-square (scale_covar=True) + residual = y - design @ beta + chi2 = float(np.sum((residual / sigma) ** 2)) + reduced_chi2 = chi2 / (q.size - 2) + expected_errors = np.sqrt(np.diag(covariance) * reduced_chi2) + assert model.scale.error == pytest.approx(expected_errors[0], rel=0.05) + assert model.background.error == pytest.approx(expected_errors[1], rel=0.05) diff --git a/tests/test_project.py b/tests/test_project.py index b1ae72eb..62dd67d2 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -19,6 +19,7 @@ from easyreflectometry.model import Model from easyreflectometry.model import ModelCollection from easyreflectometry.model import PercentageFwhm +from easyreflectometry.model import Pointwise from easyreflectometry.project import Project from easyreflectometry.sample import Layer from easyreflectometry.sample import Material @@ -476,7 +477,7 @@ def test_as_dict_minimizer(self): project = Project() project._fitter = MagicMock() project._fitter.easy_science_multi_fitter = MagicMock() - project._fitter.easy_science_multi_fitter.minimizer.enum = AvailableMinimizers.LMFit + project._fitter.easy_science_multi_fitter.minimizer = AvailableMinimizers.LMFit # Then project_dict = project.as_dict() @@ -663,7 +664,8 @@ def test_load_experiment(self): assert isinstance(project.experiments[5], DataSet1D) assert project.experiments[5].name == 'Example data file from refnx docs' assert project.experiments[5].model == model_5 - assert isinstance(project.models[5].resolution_function, PercentageFwhm) + # example.ort carries an sQz column, so the measured resolution is used + assert isinstance(project.models[5].resolution_function, Pointwise) assert isinstance(project.models[4].resolution_function, PercentageFwhm) def test_load_experiment_sets_resolution_function_pointwise_when_xe_present(self, tmp_path): @@ -679,12 +681,13 @@ def test_load_experiment_sets_resolution_function_pointwise_when_xe_present(self # Then project.load_experiment_for_model_at_index(str(fpath)) - # Resolution is always set to PercentageFwhm - from easyreflectometry.model.resolution_functions import PercentageFwhm + # Expect Pointwise because xe (q-resolution) is present + resolution_function = project.models[0].resolution_function + assert isinstance(resolution_function, Pointwise) + # The 4th column is sQz (sigma); smearing() must return it unchanged + assert_allclose(resolution_function.smearing([0.01, 0.02]), [1e-4, 1e-4]) - assert isinstance(project.models[0].resolution_function, PercentageFwhm) - - def test_load_experiment_sets_linearspline_when_only_ye_present(self, tmp_path): + def test_load_experiment_keeps_percentage_fwhm_when_no_xe(self, tmp_path): # When global_object.map._clear() project = Project() @@ -697,11 +700,45 @@ def test_load_experiment_sets_linearspline_when_only_ye_present(self, tmp_path): # Then project.load_experiment_for_model_at_index(str(fpath)) - # Resolution is always set to PercentageFwhm - from easyreflectometry.model.resolution_functions import PercentageFwhm - + # No q-resolution data available, so the 5% FWHM default is kept assert isinstance(project.models[0].resolution_function, PercentageFwhm) + def test_apply_resolution_function_prefers_pointwise_falls_back_to_percentage(self): + # When + global_object.map._clear() + project = Project() + model = Model() + with_xe = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1], xe=[1e-8, 4e-8]) + zero_xe = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1], xe=[0.0, 0.0]) + no_xe = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1]) + + # Then Expect + project._apply_resolution_function(with_xe, model) + assert isinstance(model.resolution_function, Pointwise) + # xe holds sQz variances; smearing() must return sigma = sqrt(xe) + assert_allclose(model.resolution_function.smearing([0.01, 0.02]), [1e-4, 2e-4]) + + project._apply_resolution_function(zero_xe, model) + assert isinstance(model.resolution_function, PercentageFwhm) + + project._apply_resolution_function(no_xe, model) + assert isinstance(model.resolution_function, PercentageFwhm) + + def test_load_all_experiments_from_file_sets_pointwise_when_sqz_present(self): + # When + global_object.map._clear() + project = Project() + project.models = ModelCollection(Model()) + fpath = os.path.join(PATH_STATIC, 'test_example2.ort') + + # Then + n_loaded = project.load_all_experiments_from_file(fpath) + + # Expect + assert n_loaded == 2 + assert list(project.experiments.keys()) == [0, 1] + assert isinstance(project.models[0].resolution_function, Pointwise) + def test_experimental_data_at_index(self): # When global_object.map._clear() diff --git a/tests/test_topmost_nesting.py b/tests/test_topmost_nesting.py index 1003efe5..622991b2 100644 --- a/tests/test_topmost_nesting.py +++ b/tests/test_topmost_nesting.py @@ -47,8 +47,8 @@ def test_copy(): assert model._resolution_function.smearing(5.5) == model_copy._resolution_function.smearing(5.5) assert model.interface().name == model_copy.interface().name assert_almost_equal( - model.interface().reflectivity_profile([0.3], model.unique_name), - model_copy.interface().reflectivity_profile([0.3], model_copy.unique_name), + model.interface().reflectity_profile([0.3], model.unique_name), + model_copy.interface().reflectity_profile([0.3], model_copy.unique_name), ) assert model.unique_name != model_copy.unique_name assert model.name == model_copy.name diff --git a/tests/unit/test_fitting_mcmc.py b/tests/unit/test_fitting_mcmc.py new file mode 100644 index 00000000..ec2e67ec --- /dev/null +++ b/tests/unit/test_fitting_mcmc.py @@ -0,0 +1,220 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Unit tests for the ``Sampler``-based MCMC workflow in ``MultiFitter.mcmc_sample``. + +The actual BUMPS/DREAM sampling is delegated to ``easyscience.fitting.Sampler``; +these tests mock the ``Sampler`` class so they stay fast while still exercising +the wrapper logic: data preparation, zero-variance guards, warning emission, +result-dict construction, and retention of the sampler for chain extension. +""" + +from unittest.mock import MagicMock +from unittest.mock import patch + +import numpy as np +import pytest +import scipp as sc +from easyscience import global_object +from easyscience.fitting.minimizers.factory import AvailableMinimizers + +from easyreflectometry.calculators import CalculatorFactory +from easyreflectometry.fitting import MultiFitter +from easyreflectometry.fitting import _fit_result_reduced_chi +from easyreflectometry.fitting import _flatten_list +from easyreflectometry.model import Model + + +@pytest.fixture(autouse=True) +def clear_global_map(): + global_object.map._clear() + yield + global_object.map._clear() + + +def _make_fitter() -> MultiFitter: + model = Model() + model.interface = CalculatorFactory() + return MultiFitter(model) + + +def _make_bumps_fitter() -> MultiFitter: + """A MultiFitter whose core fitter reports a BUMPS minimizer without running one.""" + fitter = _make_fitter() + fitter.easy_science_multi_fitter = MagicMock() + fitter.easy_science_multi_fitter.minimizer.package = 'bumps' + return fitter + + +def _make_data(variances: np.ndarray, n: int = 10) -> sc.DataGroup: + return sc.DataGroup({ + 'coords': {'Qz_0': sc.array(dims=['Qz_0'], values=np.linspace(0.01, 0.3, n))}, + 'data': {'R_0': sc.array(dims=['Qz_0'], values=np.ones(n), variances=variances)}, + }) + + +def _fake_sampling_results(): + results = MagicMock() + results.draws = np.ones((10, 2)) + results.param_names = ['a', 'b'] + results.state = object() + results.logp = np.zeros(10) + return results + + +def _patch_sampler(capture: dict, results=None): + """Patch ``easyreflectometry.fitting.Sampler`` recording ctor and sample() args.""" + results = results if results is not None else _fake_sampling_results() + + def _ctor(fitter, *, x, y, weights, **kwargs): + capture['fitter'] = fitter + capture['x'] = x + capture['y'] = y + capture['weights'] = weights + instance = MagicMock() + + def _sample(**sample_kwargs): + capture.update(sample_kwargs) + return results + + instance.sample = MagicMock(side_effect=_sample) + capture['instance'] = instance + return instance + + return patch('easyreflectometry.fitting.Sampler', side_effect=_ctor) + + +class TestMCMCSampleGuards: + def test_raises_runtime_error_when_minimizer_is_not_bumps(self): + fitter = _make_fitter() # default minimizer is LMFit, not BUMPS + data = _make_data(np.ones(10) * 0.01) + + with pytest.raises(RuntimeError, match='Bayesian sampling requires a BUMPS minimizer'): + fitter.mcmc_sample(data) + + def test_all_zero_variance_raises_value_error(self): + """Sampling without any uncertainties has no defined likelihood.""" + fitter = _make_bumps_fitter() + data = _make_data(np.zeros(10)) + + capture = {} + with _patch_sampler(capture) as sampler_cls: + with pytest.raises(ValueError, match='all points have zero variance'): + fitter.mcmc_sample(data) + sampler_cls.assert_not_called() + + def test_all_zero_variance_allowed_with_mighell_objective(self): + """objective='mighell' is the explicit opt-in for missing uncertainties.""" + fitter = _make_bumps_fitter() + data = _make_data(np.zeros(10)) + + capture = {} + with _patch_sampler(capture): + with pytest.warns(UserWarning, match='Mighell transform to all'): + result = fitter.mcmc_sample(data, samples=100, burn=10, thin=2, objective='mighell') + assert set(result) == {'draws', 'param_names', 'state', 'logp'} + + +class TestMCMCSampleWarnings: + def test_legacy_mask_warns_about_masked_points(self): + fitter = _make_bumps_fitter() + variances = np.ones(10) * 0.01 + variances[3] = 0.0 + data = _make_data(variances) + + capture = {} + with _patch_sampler(capture): + with pytest.warns(UserWarning, match='Masked 1 data point'): + fitter.mcmc_sample(data, samples=100, burn=10, thin=2, objective='legacy_mask') + # The masked point must not reach the Sampler + assert len(capture['x'][0]) == 9 + + def test_hybrid_warns_about_mighell_substitution(self): + fitter = _make_bumps_fitter() + variances = np.ones(10) * 0.01 + variances[3] = 0.0 + data = _make_data(variances) + + capture = {} + with _patch_sampler(capture): + with pytest.warns(UserWarning, match='Mighell substitution to 1'): + fitter.mcmc_sample(data, samples=100, burn=10, thin=2) + # Hybrid keeps every point + assert len(capture['x'][0]) == 10 + + +class TestMCMCSampleDispatch: + def test_returns_dict_built_from_sampling_results(self): + fitter = _make_bumps_fitter() + data = _make_data(np.ones(10) * 0.01) + results = _fake_sampling_results() + + capture = {} + with _patch_sampler(capture, results=results): + result = fitter.mcmc_sample(data, samples=100, burn=20, thin=2, population=5) + + assert capture['fitter'] is fitter.easy_science_multi_fitter + assert result['draws'] is results.draws + assert result['param_names'] == results.param_names + assert result['state'] is results.state + assert result['logp'] is results.logp + + def test_forwards_hyperparameters_to_sampler_sample(self): + fitter = _make_bumps_fitter() + data = _make_data(np.ones(10) * 0.01) + + capture = {} + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=500, burn=100, thin=5, population=8) + assert capture['samples'] == 500 + assert capture['burn'] == 100 + assert capture['thin'] == 5 + assert capture['population'] == 8 + assert capture['sampler_kwargs'] is None + + def test_initializer_forwarded_via_sampler_kwargs(self): + fitter = _make_bumps_fitter() + data = _make_data(np.ones(10) * 0.01) + + capture = {} + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2, initializer='lhs') + assert capture['sampler_kwargs'] == {'init': 'lhs'} + + def test_sampler_retained_for_chain_extension(self): + """The Sampler instance must be kept on ``fitter.sampler`` so the chain + can be extended with ``fitter.sampler.extend(...)`` without a new burn-in.""" + fitter = _make_bumps_fitter() + assert fitter.sampler is None + + data = _make_data(np.ones(10) * 0.01) + capture = {} + with _patch_sampler(capture): + fitter.mcmc_sample(data, samples=100, burn=20, thin=2) + + assert fitter.sampler is capture['instance'] + + +class TestMultiFitterHelpers: + def test_switch_minimizer_delegates_to_core_fitter(self): + fitter = _make_fitter() + fitter.easy_science_multi_fitter = MagicMock() + fitter.switch_minimizer(AvailableMinimizers.Bumps) + fitter.easy_science_multi_fitter.switch_minimizer.assert_called_once_with(AvailableMinimizers.Bumps) + + def test_flatten_list_flattens_nested_lists(self): + result = _flatten_list([[1, 2], [3], [4, 5]]) + assert isinstance(result, np.ndarray) + assert list(result) == [1, 2, 3, 4, 5] + + def test_fit_result_reduced_chi_raises_without_any_attribute(self): + result = MagicMock(spec=[]) # no reduced_chi, no reduced_chi2 + with pytest.raises(AttributeError, match='neither reduced_chi nor reduced_chi2'): + _fit_result_reduced_chi(result) + + def test_fit_func_computes_reflectivity_through_calculator(self): + """The factory's fit_func must evaluate the model reflectivity profile.""" + fitter = _make_fitter() + q = np.linspace(0.01, 0.1, 5) + reflectivity = fitter._fit_func[0](q) + assert np.shape(reflectivity) == (5,) + assert np.all(np.isfinite(reflectivity)) diff --git a/tests/unit/test_material_and_calculations.py b/tests/unit/test_material_and_calculations.py new file mode 100644 index 00000000..7c5977b9 --- /dev/null +++ b/tests/unit/test_material_and_calculations.py @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Unit tests for MaterialMixture derived sld/isld, special calculations, +and default parameter limits.""" + +import numpy as np +import pytest +from easyscience import global_object +from easyscience.variable import Parameter + +from easyreflectometry.limits import apply_default_limits +from easyreflectometry.sample import Material +from easyreflectometry.sample.elements.materials.material_mixture import MaterialMixture +from easyreflectometry.special.calculations import molecular_weight +from easyreflectometry.special.calculations import neutron_scattering_length +from easyreflectometry.special.calculations import weighted_average + + +@pytest.fixture(autouse=True) +def clear_global_map(): + global_object.map._clear() + yield + global_object.map._clear() + + +class TestMaterialMixtureSld: + def test_sld_and_isld_are_floats_from_weighted_average(self): + material_a = Material(name='A', sld=2.0, isld=0.5) + material_b = Material(name='B', sld=6.0, isld=1.5) + mixture = MaterialMixture(material_a=material_a, material_b=material_b, fraction=0.25) + + assert isinstance(mixture.sld, float) + assert isinstance(mixture.isld, float) + assert mixture.sld == pytest.approx(weighted_average(2.0, 6.0, 0.25)) + assert mixture.isld == pytest.approx(weighted_average(0.5, 1.5, 0.25)) + + def test_sld_and_isld_follow_fraction_changes(self): + material_a = Material(name='A', sld=2.0, isld=0.0) + material_b = Material(name='B', sld=6.0, isld=1.0) + mixture = MaterialMixture(material_a=material_a, material_b=material_b, fraction=0.25) + + mixture.fraction = 0.75 + + assert mixture.sld == pytest.approx(5.0) + assert mixture.isld == pytest.approx(0.75) + + +class TestNeutronScatteringLength: + def test_element_without_absorption_has_zero_imaginary_part(self): + result = neutron_scattering_length('Si') + assert result.real == pytest.approx(4.1507e-05, rel=1e-3) + assert result.imag == 0.0 + + def test_element_with_absorption_has_negative_imaginary_part(self): + # Boron has a non-zero imaginary bound coherent scattering length (b_c_i) + result = neutron_scattering_length('B') + assert result.real == pytest.approx(5.3e-05, rel=1e-3) + assert result.imag == pytest.approx(-2.1e-06, rel=1e-3) + + def test_formula_scales_with_stoichiometry(self): + single = neutron_scattering_length('B') + double = neutron_scattering_length('B2') + assert double.real == pytest.approx(2 * single.real) + assert double.imag == pytest.approx(2 * single.imag) + + +class TestMolecularWeight: + def test_molecular_weight_of_water(self): + assert molecular_weight('H2O') == pytest.approx(18.015, rel=1e-3) + + +class TestApplyDefaultLimits: + def test_percentage_limits_set_for_infinite_bounds(self): + param = Parameter('thickness', 10.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'thickness') + assert param.min == pytest.approx(5.0) + assert param.max == pytest.approx(20.0) + + def test_percentage_limits_leave_finite_bounds_untouched(self): + param = Parameter('roughness', 10.0, min=2.0, max=30.0) + apply_default_limits(param, 'roughness') + assert param.min == 2.0 + assert param.max == 30.0 + + def test_percentage_limits_skip_zero_value(self): + param = Parameter('thickness', 0.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'thickness') + assert np.isinf(param.min) + assert np.isinf(param.max) + + def test_sld_gets_fixed_limits(self): + param = Parameter('sld', 4.0, min=-np.inf, max=np.inf) + apply_default_limits(param, 'sld') + assert param.min == -1.0 + assert param.max == 10.0 diff --git a/tests/unit/test_project_core.py b/tests/unit/test_project_core.py new file mode 100644 index 00000000..5a227255 --- /dev/null +++ b/tests/unit/test_project_core.py @@ -0,0 +1,143 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Unit tests for Project material-index helpers, resolution auto-selection, +ORSO loading, model data generation, and minimizer serialization.""" + +import os + +import numpy as np +import pytest +from easyscience import global_object + +import easyreflectometry +from easyreflectometry.data import DataSet1D +from easyreflectometry.model import PercentageFwhm +from easyreflectometry.model import Pointwise +from easyreflectometry.project import Project + +PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') + + +@pytest.fixture(autouse=True) +def clear_global_map(): + global_object.map._clear() + yield + global_object.map._clear() + + +@pytest.fixture +def project() -> Project: + return Project() + + +class TestGetIndexMaterials: + def test_get_index_air_adds_material_when_missing(self, project: Project): + assert len(project._materials) == 0 + index = project.get_index_air() + assert project._materials[index].name == 'Air' + assert project._materials[index].sld.value == 0.0 + + def test_get_index_si_adds_material_when_missing(self, project: Project): + index = project.get_index_si() + assert project._materials[index].name == 'Si' + assert project._materials[index].sld.value == 2.07 + + def test_get_index_sio2_adds_material_when_missing(self, project: Project): + index = project.get_index_sio2() + assert project._materials[index].name == 'SiO2' + assert project._materials[index].sld.value == 3.47 + + def test_get_index_d2o_adds_material_when_missing(self, project: Project): + index = project.get_index_d2o() + assert project._materials[index].name == 'D2O' + assert project._materials[index].sld.value == 6.36 + + def test_get_index_is_idempotent(self, project: Project): + first = project.get_index_d2o() + count_after_first = len(project._materials) + second = project.get_index_d2o() + assert first == second + assert len(project._materials) == count_after_first + + def test_indices_point_at_distinct_materials(self, project: Project): + indices = { + 'Air': project.get_index_air(), + 'D2O': project.get_index_d2o(), + 'Si': project.get_index_si(), + 'SiO2': project.get_index_sio2(), + } + assert len(set(indices.values())) == 4 + for name, index in indices.items(): + assert project._materials[index].name == name + + +class TestApplyResolutionFunction: + def test_pointwise_used_when_experiment_has_q_variances(self, project: Project): + project.default_model() + model = project.models[0] + experiment = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1], xe=[1e-8, 4e-8]) + + project._apply_resolution_function(experiment, model) + + assert isinstance(model.resolution_function, Pointwise) + # sigma at the data points is sqrt(sQz) + np.testing.assert_allclose(model.resolution_function.smearing(), np.sqrt([1e-8, 4e-8])) + + def test_percentage_fwhm_fallback_when_q_variances_all_zero(self, project: Project): + project.default_model() + model = project.models[0] + experiment = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1], xe=[0.0, 0.0]) + + project._apply_resolution_function(experiment, model) + + assert isinstance(model.resolution_function, PercentageFwhm) + assert model.resolution_function.constant == 5.0 + + def test_percentage_fwhm_fallback_when_q_variances_absent(self, project: Project): + project.default_model() + model = project.models[0] + experiment = DataSet1D(x=[0.01, 0.02], y=[1.0, 2.0], ye=[0.1, 0.1]) + + project._apply_resolution_function(experiment, model) + + assert isinstance(model.resolution_function, PercentageFwhm) + + +class TestLoadOrsoFile: + def test_load_orso_file_creates_model_and_experiment(self, project: Project): + with pytest.warns(UserWarning): + project.load_orso_file(os.path.join(PATH_STATIC, 'example.ort')) + + assert len(project.models) == 1 + assert len(project.experiments) == 1 + assert project.experiments[0].name == 'Experiment from ORSO' + assert project.experiments[0].model is project.models[0] + assert project._with_experiments is True + + +class TestModelData: + def test_model_data_for_model_at_index_returns_reflectivity(self, project: Project): + project.default_model() + q_range = np.linspace(0.01, 0.1, 5) + + dataset = project.model_data_for_model_at_index(0, q_range=q_range) + + np.testing.assert_array_equal(dataset.x, q_range) + assert dataset.y.shape == (5,) + assert np.all(np.isfinite(dataset.y)) + # Reflectivity near total reflection is of order unity and decays with q + assert dataset.y[0] > dataset.y[-1] + + +class TestAsDictMinimizer: + def test_as_dict_uses_selection_when_no_fitter_exists(self, project: Project): + # No models -> the lazy fitter property stays None -> fall back to selection + project_dict = project.as_dict() + assert project._fitter is None + assert project_dict['fitter_minimizer'] == project._minimizer_selection.name + + def test_as_dict_reads_minimizer_from_fitter_when_models_exist(self, project: Project): + project.default_model() + project_dict = project.as_dict() + assert project._fitter is not None + assert project_dict['fitter_minimizer'] == project._fitter.easy_science_multi_fitter.minimizer.name diff --git a/tests/unit/test_summary_goodness_of_fit.py b/tests/unit/test_summary_goodness_of_fit.py new file mode 100644 index 00000000..cb1fb427 --- /dev/null +++ b/tests/unit/test_summary_goodness_of_fit.py @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Unit tests for the summary goodness-of-fit computation and refinement section.""" + +from unittest.mock import MagicMock + +import pytest +from easyscience import global_object + +from easyreflectometry import Project +from easyreflectometry.summary import Summary + + +@pytest.fixture +def project() -> Project: + global_object.map._clear() + project = Project() + project.default_model() + return project + + +def _fit_result(chi2=None, reduced_chi2=None, n_points=0, n_pars=0): + result = MagicMock() + result.chi2 = chi2 + result.reduced_chi2 = reduced_chi2 + result.x = list(range(n_points)) + result.n_pars = n_pars + return result + + +class TestComputeGoodnessOfFit: + def test_returns_na_when_no_fit_has_been_run(self, project: Project): + summary = Summary(project) + assert summary._compute_goodness_of_fit() == 'N/A' + + def test_returns_na_when_last_fit_results_is_empty(self, project: Project): + project._last_fit_results = [] + summary = Summary(project) + assert summary._compute_goodness_of_fit() == 'N/A' + + def test_single_result_uses_its_reduced_chi2(self, project: Project): + project._last_fit_results = [_fit_result(reduced_chi2=1.2345)] + summary = Summary(project) + assert summary._compute_goodness_of_fit() == '1.234' + + def test_multiple_results_aggregate_over_global_dof(self, project: Project): + # total chi2 = 30, total points = 16, n_pars = 6 -> dof = 10 -> gof = 3 + project._last_fit_results = [ + _fit_result(chi2=10.0, n_points=8, n_pars=6), + _fit_result(chi2=20.0, n_points=8, n_pars=6), + ] + summary = Summary(project) + assert summary._compute_goodness_of_fit() == '3' + + def test_multiple_results_with_nonpositive_dof_return_zero(self, project: Project): + project._last_fit_results = [ + _fit_result(chi2=10.0, n_points=2, n_pars=6), + _fit_result(chi2=20.0, n_points=2, n_pars=6), + ] + summary = Summary(project) + assert summary._compute_goodness_of_fit() == '0' + + def test_returns_na_when_result_values_are_invalid(self, project: Project): + project._last_fit_results = [_fit_result(reduced_chi2='not-a-number')] + summary = Summary(project) + assert summary._compute_goodness_of_fit() == 'N/A' + + +class TestRefinementSection: + def test_refinement_section_renders_counts_and_gof(self, project: Project): + project._last_fit_results = [_fit_result(reduced_chi2=2.5)] + summary = Summary(project) + + html = summary._refinement_section() + + assert '2.5' in html + # every placeholder must have been substituted with a number + for placeholder in ( + 'num_total_params', + 'num_free_params', + 'num_fixed_params', + 'num_constriants', + 'num_constraints', + 'goodness_of_fit', + ): + assert placeholder not in html From 576d45becce0aeeb9960dbb9b10351fc6784570d Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 31 Jul 2026 12:42:24 +0200 Subject: [PATCH 20/22] reparented easyscience, updated CHANGELOG --- CHANGELOG.md | 2 +- pyproject.toml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55aafcae..938f27b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# Version 1.7.0 (1 Aug 2026) Restored the measured per-point resolution on data load (issue #368). diff --git a/pyproject.toml b/pyproject.toml index ac183b21..9f90457f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,7 @@ classifiers = [ ] requires-python = '>=3.11' dependencies = [ - 'easyscience @ git+https://github.com/easyscience/corelib.git@develop', - # 'easyscience', + 'easyscience', 'scipp', 'refnx', 'refl1d>=1.0.0', From eb381d9726906c8dd803f6d26a02b6f7dad7fd5e Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 31 Jul 2026 13:37:31 +0200 Subject: [PATCH 21/22] codecov related fixes (#391) --- pixi.toml | 6 +- tests/test_bayesian.py | 406 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 411 insertions(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index ab6c977e..f0023fba 100644 --- a/pixi.toml +++ b/pixi.toml @@ -92,7 +92,11 @@ user = { features = ['py-max', 'user'] } # 🧪 Testing Tasks ################## -unit-tests = 'python -m pytest tests/unit/ --color=yes -v' +# The bulk of the unit-test suite still lives at the top level of tests/ +# (pending migration into tests/unit/), so run the whole tree minus the +# functional and integration subtrees -- otherwise CI coverage only sees +# the handful of files under tests/unit/. +unit-tests = 'python -m pytest tests/ --ignore=tests/functional --ignore=tests/integration --color=yes -v' functional-tests = 'python -m pytest tests/functional/ --color=yes -v' # No -n auto: importing easyreflectometry pulls in arviz, and arviz 0.23.4 # (py-311-env) writes a "warn once per day" stamp file on import via a diff --git a/tests/test_bayesian.py b/tests/test_bayesian.py index 15404645..1cb78d4f 100644 --- a/tests/test_bayesian.py +++ b/tests/test_bayesian.py @@ -474,3 +474,409 @@ def test_in_analysis_namespace(self): assert hasattr(analysis, 'plot_distribution') assert 'plot_distribution' in analysis.__all__ + + +# =================================================================== +# Label wrapping helper +# =================================================================== + + +class TestWrapPairLabel: + def test_empty_string_unchanged(self): + from easyreflectometry.analysis.bayesian import _wrap_pair_label + + assert _wrap_pair_label('') == '' + + def test_short_name_unchanged(self): + from easyreflectometry.analysis.bayesian import _wrap_pair_label + + assert _wrap_pair_label('thickness') == 'thickness' + + def test_dotted_name_breaks_on_dots(self): + from easyreflectometry.analysis.bayesian import _wrap_pair_label + + assert _wrap_pair_label('layer1.thickness') == 'layer1.
thickness' + + def test_long_multiword_name_wraps(self): + from easyreflectometry.analysis.bayesian import _wrap_pair_label + + wrapped = _wrap_pair_label('a very long parameter name indeed', max_len=16) + assert '
' in wrapped + assert wrapped.replace('
', ' ') == 'a very long parameter name indeed' + + def test_long_single_word_unchanged(self): + from easyreflectometry.analysis.bayesian import _wrap_pair_label + + name = 'averyveryverylongsingleword' + assert _wrap_pair_label(name, max_len=16) == name + + +# =================================================================== +# Optional-dependency guards +# =================================================================== + + +class TestRequireHelpers: + def test_require_arviz_raises_when_unavailable(self, monkeypatch): + from easyreflectometry.analysis import bayesian as bayesian_mod + + monkeypatch.setattr(bayesian_mod, '_HAS_ARVIZ', False) + with pytest.raises(ImportError, match='arviz'): + bayesian_mod._require_arviz() + + def test_require_plotly_raises_when_unavailable(self, monkeypatch): + import builtins + + from easyreflectometry.analysis.bayesian import _require_plotly + + real_import = builtins.__import__ + + def _fake_import(name, *args, **kwargs): + if name.startswith('plotly'): + raise ImportError('plotly disabled for test') + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, '__import__', _fake_import) + with pytest.raises(ImportError, match='plotly'): + _require_plotly() + + def test_gelman_rubin_warns_and_returns_none_without_arviz(self, sample_draws, monkeypatch): + from easyreflectometry.analysis import bayesian as bayesian_mod + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + pr = PosteriorResults(draws, param_names) + monkeypatch.setattr(bayesian_mod, '_HAS_ARVIZ', False) + with pytest.warns(UserWarning, match='arviz'): + result = pr.gelman_rubin() + assert result is None + + +# =================================================================== +# arviz data conversion +# =================================================================== + + +class TestToArvizData: + def test_2d_draws_become_single_chain(self, sample_draws): + pytest.importorskip('arviz') + from easyreflectometry.analysis.bayesian import _to_arviz_data + + draws, param_names = sample_draws + idata = _to_arviz_data(draws, param_names) + posterior = idata.posterior + assert posterior.sizes['chain'] == 1 + assert posterior.sizes['draw'] == draws.shape[0] + for name in param_names: + assert name in posterior + + +# =================================================================== +# Plot construction (plotly available) +# =================================================================== + + +class TestPlotTraceFigure: + def test_returns_figure_for_2d_draws(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import plot_trace + + draws, param_names = sample_draws + fig = plot_trace(draws, param_names, return_figure=True) + assert isinstance(fig, Figure) + # One line trace and one histogram per parameter for the single chain. + assert len(fig.data) == 2 * len(param_names) + + def test_returns_figure_for_multi_chain_draws(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import plot_trace + + draws, param_names = sample_draws + multi = np.stack([draws, draws + 1.0], axis=0) # (2, n_draws, n_params) + fig = plot_trace(multi, param_names, return_figure=True) + assert isinstance(fig, Figure) + assert len(fig.data) == 2 * 2 * len(param_names) + + def test_inline_path_delegates_to_arviz(self, sample_draws, monkeypatch): + pytest.importorskip('arviz') + from unittest.mock import MagicMock + + from easyreflectometry.analysis import bayesian as bayesian_mod + + draws, param_names = sample_draws + mock_plot = MagicMock() + monkeypatch.setattr(bayesian_mod._arviz, 'plot_trace', mock_plot) + result = bayesian_mod.plot_trace(draws, param_names) + assert result is None + mock_plot.assert_called_once() + + +class TestPlotDistributionFigure: + def test_returns_none_without_return_figure(self, sample_draws): + from easyreflectometry.analysis.bayesian import plot_distribution + + draws, param_names = sample_draws + assert plot_distribution(draws, param_names) is None + + def test_returns_figure_with_expected_overlays(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import plot_distribution + + draws, param_names = sample_draws + logp = np.arange(draws.shape[0], dtype=float) + fig = plot_distribution(draws, param_names, logp=logp, return_figure=True) + assert isinstance(fig, Figure) + trace_names = {trace.name for trace in fig.data} + assert 'Posterior histogram' in trace_names + assert '95% credible interval' in trace_names + assert 'Median' in trace_names + # logp was supplied, so the best posterior sample line must be drawn. + assert 'Best posterior sample' in trace_names + + def test_accepts_3d_draws(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import plot_distribution + + draws, param_names = sample_draws + multi = np.stack([draws, draws], axis=0) # (2, n_draws, n_params) + fig = plot_distribution(multi, param_names, return_figure=True) + assert isinstance(fig, Figure) + + +class TestPosteriorResultsPlotDelegates: + def test_corner_returns_figure(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + fig = PosteriorResults(draws, param_names).corner() + assert isinstance(fig, Figure) + + def test_distribution_returns_figure(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + fig = PosteriorResults(draws, param_names).distribution() + assert isinstance(fig, Figure) + + def test_trace_delegates_to_plot_trace(self, sample_draws, monkeypatch): + from unittest.mock import MagicMock + + from easyreflectometry.analysis import bayesian as bayesian_mod + from easyreflectometry.analysis.bayesian import PosteriorResults + + draws, param_names = sample_draws + mock_plot = MagicMock() + monkeypatch.setattr(bayesian_mod, 'plot_trace', mock_plot) + PosteriorResults(draws, param_names).trace() + mock_plot.assert_called_once() + + +class TestPlotCornerEdgeCases: + def test_accepts_3d_draws(self, sample_draws): + Figure = pytest.importorskip('plotly.graph_objects').Figure + from easyreflectometry.analysis.bayesian import plot_corner + + draws, param_names = sample_draws + multi = np.stack([draws, draws], axis=0) + fig = plot_corner(multi, param_names) + assert isinstance(fig, Figure) + + def test_thins_scatter_for_large_posteriors(self): + go = pytest.importorskip('plotly.graph_objects') + from easyreflectometry.analysis.bayesian import _POSTERIOR_PAIR_SCATTER_MAX_POINTS + from easyreflectometry.analysis.bayesian import plot_corner + + rng = np.random.default_rng(3) + n_samples = _POSTERIOR_PAIR_SCATTER_MAX_POINTS * 2 + draws = rng.normal(size=(n_samples, 2)) + fig = plot_corner(draws, ['a', 'b']) + scatters = [t for t in fig.data if isinstance(t, go.Scatter) and t.name == 'Posterior samples'] + assert scatters + assert all(len(t.x) <= _POSTERIOR_PAIR_SCATTER_MAX_POINTS for t in scatters) + + def test_single_sample_falls_back_to_histogram(self): + go = pytest.importorskip('plotly.graph_objects') + from easyreflectometry.analysis.bayesian import plot_corner + + # A single draw defeats the KDE, so the diagonal must fall back to a + # histogram and the pair panels must omit contours. + draws = np.array([[250.0, 2.0]]) + fig = plot_corner(draws, ['thickness', 'sld']) + assert any(isinstance(t, go.Histogram) for t in fig.data) + assert not any(isinstance(t, go.Contour) for t in fig.data) + + +# =================================================================== +# Density-estimation helpers +# =================================================================== + + +class TestPosteriorAxisBounds: + def test_empty_returns_none(self): + from easyreflectometry.analysis.bayesian import _posterior_axis_bounds + + assert _posterior_axis_bounds(np.array([])) is None + assert _posterior_axis_bounds(np.array([np.nan, np.inf])) is None + + def test_constant_values_get_padding(self): + from easyreflectometry.analysis.bayesian import _posterior_axis_bounds + + lo, hi = _posterior_axis_bounds(np.array([5.0, 5.0, 5.0])) + assert lo < 5.0 < hi + + def test_constant_zero_gets_padding(self): + from easyreflectometry.analysis.bayesian import _posterior_axis_bounds + + lo, hi = _posterior_axis_bounds(np.zeros(3)) + assert lo < 0.0 < hi + + +class TestPosteriorDensityCurve: + def test_too_few_samples_returns_none(self): + from easyreflectometry.analysis.bayesian import _posterior_density_curve + + assert _posterior_density_curve(np.array([1.0])) is None + + def test_constant_samples_yield_gaussian_bump(self): + pytest.importorskip('scipy') + from easyreflectometry.analysis.bayesian import _posterior_density_curve + + result = _posterior_density_curve(np.full(50, 3.0)) + assert result is not None + grid, density = result + # Density peaks at the constant value and integrates to ~1. + assert grid[np.argmax(density)] == pytest.approx(3.0, abs=(grid[1] - grid[0])) + assert np.trapezoid(density, grid) == pytest.approx(1.0, rel=1e-6) + + def test_returns_none_without_scipy(self, sample_draws, monkeypatch): + import builtins + + from easyreflectometry.analysis.bayesian import _posterior_density_curve + + real_import = builtins.__import__ + + def _fake_import(name, *args, **kwargs): + if name.startswith('scipy'): + raise ImportError('scipy disabled for test') + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, '__import__', _fake_import) + draws, _ = sample_draws + assert _posterior_density_curve(draws[:, 0]) is None + + +class TestPosteriorDensitySurface: + def test_degenerate_samples_return_none(self): + pytest.importorskip('scipy') + from easyreflectometry.analysis.bayesian import _posterior_density_surface + + constant = np.full(50, 1.0) + # Both axes constant. + assert _posterior_density_surface(constant, constant) is None + # One axis constant: rank-deficient covariance. + rng = np.random.default_rng(11) + assert _posterior_density_surface(constant, rng.normal(size=50)) is None + + def test_too_few_finite_samples_return_none(self): + pytest.importorskip('scipy') + from easyreflectometry.analysis.bayesian import _posterior_density_surface + + x = np.array([1.0, np.nan, np.nan]) + y = np.array([2.0, np.nan, np.nan]) + assert _posterior_density_surface(x, y) is None + + def test_valid_samples_return_grids(self, sample_draws): + pytest.importorskip('scipy') + from easyreflectometry.analysis.bayesian import _posterior_density_surface + + draws, _ = sample_draws + result = _posterior_density_surface(draws[:, 0], draws[:, 1]) + assert result is not None + x_grid, y_grid, density = result + assert density.shape == (len(y_grid), len(x_grid)) + + def test_returns_none_without_scipy(self, sample_draws, monkeypatch): + import builtins + + from easyreflectometry.analysis.bayesian import _posterior_density_surface + + real_import = builtins.__import__ + + def _fake_import(name, *args, **kwargs): + if name.startswith('scipy'): + raise ImportError('scipy disabled for test') + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, '__import__', _fake_import) + draws, _ = sample_draws + assert _posterior_density_surface(draws[:, 0], draws[:, 1]) is None + + +class TestPosteriorContourColorscales: + def test_negative_correlation_selects_red_palette(self): + from easyreflectometry.analysis.bayesian import _POSTERIOR_NEGATIVE_CONTOUR_FILL_COLORSCALE + from easyreflectometry.analysis.bayesian import _posterior_contour_colorscales + + x = np.linspace(0, 1, 50) + fill, _ = _posterior_contour_colorscales(x, -x) + assert fill is _POSTERIOR_NEGATIVE_CONTOUR_FILL_COLORSCALE + + def test_positive_correlation_selects_blue_palette(self): + from easyreflectometry.analysis.bayesian import _POSTERIOR_CONTOUR_FILL_COLORSCALE + from easyreflectometry.analysis.bayesian import _posterior_contour_colorscales + + x = np.linspace(0, 1, 50) + fill, _ = _posterior_contour_colorscales(x, x) + assert fill is _POSTERIOR_CONTOUR_FILL_COLORSCALE + + +class TestPosteriorMarginalYRange: + def test_covers_histogram_and_kde_peaks(self, sample_draws): + from easyreflectometry.analysis.bayesian import _posterior_density_curve + from easyreflectometry.analysis.bayesian import _posterior_marginal_y_range + + draws, _ = sample_draws + values = draws[:, 0] + curve = _posterior_density_curve(values) + y_range = _posterior_marginal_y_range(values, curve) + assert y_range is not None + lo, hi = y_range + assert lo == 0.0 + hist, _ = np.histogram(values, bins=40, density=True) + assert hi >= np.max(hist) + + def test_no_data_returns_none(self): + from easyreflectometry.analysis.bayesian import _posterior_marginal_y_range + + assert _posterior_marginal_y_range(np.array([]), None) is None + + +# =================================================================== +# Metadata helpers +# =================================================================== + + +class TestMetadataHelpers: + def test_version_returns_string(self): + from easyreflectometry.analysis.bayesian import _easyreflectometry_version + + assert isinstance(_easyreflectometry_version(), str) + + def test_data_fingerprint_is_deterministic(self): + from easyreflectometry.analysis.bayesian import _data_fingerprint + + x = [np.array([1.0, 2.0])] + y = [np.array([3.0, 4.0])] + w = [np.array([0.1, 0.2])] + first = _data_fingerprint(x, y, w) + assert isinstance(first, str) + assert len(first) == 64 + assert _data_fingerprint(x, y, w) == first + assert _data_fingerprint(x, y, [np.array([0.1, 0.3])]) != first + + def test_data_fingerprint_returns_none_on_bad_input(self): + from easyreflectometry.analysis.bayesian import _data_fingerprint + + assert _data_fingerprint([object()], [], []) is None From 299127dfa5aa08c42b382ab8aef5673f26c858ab Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Fri, 31 Jul 2026 14:30:11 +0200 Subject: [PATCH 22/22] Codecov fixes 2 (#392) * try to fix failing test * another attempt --- pixi.lock | 162 +++++++++++---------- src/easyreflectometry/analysis/bayesian.py | 9 +- tests/test_bayesian.py | 10 +- 3 files changed, 103 insertions(+), 78 deletions(-) diff --git a/pixi.lock b/pixi.lock index 36a67a04..16dba96f 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,8 +1,21 @@ version: 7 platforms: - name: linux-64 -- name: osx-arm64 + virtual-packages: + - __unix=0=0 + - __linux=4.18 + - __glibc=2.28 + - __archspec=0=x86_64 +- name: p1 + subdir: osx-arm64 + virtual-packages: + - __osx=14.0 + - __unix=0=0 + - __archspec=0=m1 - name: win-64 + virtual-packages: + - __win=10.0 + - __archspec=0=x86_64 environments: default: channels: @@ -189,8 +202,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -310,6 +322,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl @@ -326,7 +339,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -500,8 +513,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -625,6 +637,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl @@ -801,8 +814,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -928,6 +940,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl @@ -1124,8 +1137,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/06/8a/5e156e31ba656ce93c1cc895dd8f051ec351cb382940dca655aaec475005/python_bidi-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl @@ -1246,6 +1258,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl @@ -1259,7 +1272,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda @@ -1429,8 +1442,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl @@ -1553,6 +1565,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl @@ -1724,8 +1737,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -1849,6 +1861,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/0d/8882a4c7a5ebe59a46b709e82411d9c730d67250d41a2e11bc4bcd4d431d/scipp-26.3.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl @@ -2047,8 +2060,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2168,6 +2180,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/b8/ead7c10efff731738c72e59ed6eb5791854879fbed7ae98781a12006263a/lxml-6.1.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl @@ -2184,7 +2197,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/d9/8f612389178e1e1800aaed85537b024ebe28b9a82fff6a015825e51a8877/refl1d-1.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/20/2870f2e63da2b74eda896053809065769b256646bb3f4b74e06d013ad590/uritools-6.1.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -2358,8 +2371,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h4818236_10.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2483,6 +2495,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl @@ -2659,8 +2672,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h507cc87_10.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: . - - pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca + - pypi: ./ - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl - pypi: https://files.pythonhosted.org/packages/01/7c/fa07d3da2b6253eb8474be16eab2eadf670460e364ccc895ca7ff388ee30/oscrypto-1.3.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl @@ -2786,6 +2798,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/83/6d810a8a9ebc9c307989b418840c20e46907c74d707beb67ab566773e6fc/xarray-2026.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/bc/daa30c02069eeac5b9198985ba42f5d65ca71bed6705b18329e51d352b7c/plopp-26.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/99/722e90c586455733fa860d092722ef074f3a65449fe9787b7b7e2dafcd1f/pyhanko_certvalidator-0.31.1-py3-none-any.whl @@ -3070,7 +3083,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/f7/00/bbca25f8a2372465cdf93138c1e1e38dff045fb0afef1488f395d0afcb3b/ncrystal-4.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - osx-arm64: + p1: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda @@ -8297,11 +8310,11 @@ packages: purls: [] size: 388453 timestamp: 1764777142545 -- pypi: . +- pypi: ./ name: easyreflectometry requires_dist: - bumps - - easyscience @ git+https://github.com/easyscience/corelib.git@bayesian_extend + - easyscience - orsopy - plotly - pooch @@ -8345,55 +8358,6 @@ packages: - validate-pyproject[all] ; extra == 'dev' - versioningit ; extra == 'dev' requires_python: '>=3.11' -- pypi: git+https://github.com/easyscience/corelib.git?rev=bayesian_extend#8c83ab3cb6f7e598f16f31c70cc3935f326bf2ca - name: easyscience - version: 2.4.0+dev17 - requires_dist: - - asteval - - bumps - - dfo-ls - - lmfit - - numpy - - scipp - - build ; extra == 'dev' - - copier ; extra == 'dev' - - docstripy ; extra == 'dev' - - format-docstring ; extra == 'dev' - - gitpython ; extra == 'dev' - - interrogate ; extra == 'dev' - - ipykernel ; extra == 'dev' - - ipympl ; extra == 'dev' - - ipython ; extra == 'dev' - - ipywidgets ; extra == 'dev' - - jinja2 ; extra == 'dev' - - jupyterlab ; extra == 'dev' - - jupyterquiz ; extra == 'dev' - - jupytext ; extra == 'dev' - - matplotlib ; extra == 'dev' - - mike ; extra == 'dev' - - mkdocs ; extra == 'dev' - - mkdocs-autorefs ; extra == 'dev' - - mkdocs-jupyter ; extra == 'dev' - - mkdocs-markdownextradata-plugin ; extra == 'dev' - - mkdocs-material ; extra == 'dev' - - mkdocs-plugin-inline-svg ; extra == 'dev' - - mkdocstrings-python ; extra == 'dev' - - nbmake ; extra == 'dev' - - nbqa ; extra == 'dev' - - nbstripout ; extra == 'dev' - - pooch ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydoclint ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pyyaml ; extra == 'dev' - - radon ; extra == 'dev' - - ruff ; extra == 'dev' - - spdx-headers ; extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - versioningit ; extra == 'dev' - requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/00/bb/90ba423612b6aa0adccc6b1874bcd4a9b44b660c0c16f346611e00f64ac3/backrefs-7.0-py313-none-any.whl name: backrefs version: '7.0' @@ -13173,6 +13137,56 @@ packages: - nodejs ; extra == 'all' - pythreejs ; extra == 'all' requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/e6/90/90a65e6ae1b6e66183b48874d32509fc306c994beecc7924a6fa3d9f8955/easyscience-2.5.1-py3-none-any.whl + name: easyscience + version: 2.5.1 + sha256: e44c3efb10f8e040ba88523c6ba58e131e3174721f24801d036fdc5a24e622f2 + requires_dist: + - asteval + - bumps>=1.0.4 + - dfo-ls + - lmfit + - numpy + - scipp + - build ; extra == 'dev' + - copier ; extra == 'dev' + - docstripy ; extra == 'dev' + - format-docstring ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - ipykernel ; extra == 'dev' + - ipympl ; extra == 'dev' + - ipython ; extra == 'dev' + - ipywidgets ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterlab ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - matplotlib ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pooch ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pydoclint ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' + - ruff ; extra == 'dev' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' + requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl name: cycler version: 0.12.1 diff --git a/src/easyreflectometry/analysis/bayesian.py b/src/easyreflectometry/analysis/bayesian.py index 17ab252c..b5bdfb43 100644 --- a/src/easyreflectometry/analysis/bayesian.py +++ b/src/easyreflectometry/analysis/bayesian.py @@ -84,7 +84,14 @@ def _to_arviz_data(draws: np.ndarray, param_names: list[str]): for i, name in enumerate(param_names): posterior_dict[name] = draws[:, :, i] - return _arviz.from_dict({'posterior': posterior_dict}) + # arviz < 1.0 takes the posterior variables as a keyword argument; arviz + # >= 1.0 removed it in favour of a single {group: {var: array}} mapping. + # The 1.x call cannot go first: 0.x accepts the mapping without error but + # misreads it as one variable named 'posterior'. + try: + return _arviz.from_dict(posterior=posterior_dict) + except TypeError: + return _arviz.from_dict({'posterior': posterior_dict}) class PosteriorResults: diff --git a/tests/test_bayesian.py b/tests/test_bayesian.py index 1cb78d4f..6d0c3148 100644 --- a/tests/test_bayesian.py +++ b/tests/test_bayesian.py @@ -565,10 +565,14 @@ def test_2d_draws_become_single_chain(self, sample_draws): draws, param_names = sample_draws idata = _to_arviz_data(draws, param_names) posterior = idata.posterior + # Dimension naming varies across arviz versions, so assert on the + # contract itself: every sample survives conversion with its values + # intact, in a single chain. assert posterior.sizes['chain'] == 1 - assert posterior.sizes['draw'] == draws.shape[0] - for name in param_names: - assert name in posterior + for i, name in enumerate(param_names): + values = np.asarray(posterior[name].values).reshape(-1) + assert values.size == draws.shape[0] + assert np.allclose(values, draws[:, i]) # ===================================================================