diff --git a/.gitignore b/.gitignore
index 7ead58b674d77f1e0a8365223a6782df4aa527e4..2af88e4f7f93d36d627c391f55ad9e4c64c4657c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 /build/
 /temp/
+/dist/
 __pycache__
 *.egg-info
 *temp.*
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f387824b29f237d0e986b7cde4590c3a359a41dd
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,42 @@
+image: ubuntu:latest
+
+stages:
+  - code_embed
+
+variables:
+  GIT_STRATEGY: clone
+
+code_embedder:
+  stage: code_embed
+  script:
+    - echo "Personal a" 
+    - cd code-embedder/
+    - poetry install --only main
+    - README_PATHS=$(find .. -maxdepth 1 -name "*.md" -print)
+    - poetry run python ./src/main.py --readme-paths $README_PATHS
+    - cd ..
+    - README_PATHS=$(find . -maxdepth 1 -name "*.md" -print)
+    - git add $README_PATHS
+    - git diff --staged
+    - export BRANCH_NAME="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-$CI_COMMIT_REF_NAME}"
+    - echo "branch name $BRANCH_NAME"
+    - git remote set-url origin "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
+    - echo "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
+    - if ! git diff --cached --exit-code; then
+        git commit -m "Apply Code Embedder";
+        git push origin HEAD:$BRANCH_NAME;
+      else
+        echo "No changes to commit";
+      fi
+
+  before_script:
+    - apt-get update && apt-get install -y curl git python3 python3-pip
+    - curl -sSL https://install.python-poetry.org | python3 -
+    - export PATH="$HOME/.local/bin:$PATH"
+    - git clone https://github.com/kvankova/code-embedder.git
+    - git config --global user.email $GITLAB_USER_EMAIL
+    - git config --global user.name $GITLAB_USER_NAME
+  only:
+    - merge_requests
+    
+
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000000000000000000000000000000000000..c8cfe3959183f8e9a50f83f54cd723f2dc9c252d
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.10
diff --git a/CyXTraX/common/__init__.py b/CyXTraX/common/__init__.py
deleted file mode 100644
index 0bcec689802c3b6b143aec6f110b5b8d3c8ee4ee..0000000000000000000000000000000000000000
--- a/CyXTraX/common/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .mesh_object import MeshObject
\ No newline at end of file
diff --git a/CyXTraX/common/mesh_object.py b/CyXTraX/common/mesh_object.py
deleted file mode 100644
index df02eeb99f59da1facbb0c7e62702a88c93c9ac7..0000000000000000000000000000000000000000
--- a/CyXTraX/common/mesh_object.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from dataclasses import dataclass
-from pathlib import Path
-import numpy as np
-
-
-@dataclass
-class MeshObject:
-    object_path: Path
-    position_mm: np.ndarray
-    orientation_quat: np.ndarray
-
-    def as_dict(self):
-        return dict(object_path=str(self.object_path), 
-                    object_position=self.position_mm.astype(np.float64).tolist(), 
-                    object_orientation=self.orientation_quat.astype(np.float64).tolist())
-    
-    @classmethod
-    def from_dict(cls: 'MeshObject', data_dict):
-        item = cls(
-            Path(data_dict['object_path']), 
-            np.array(data_dict['object_position']), 
-            np.array(data_dict['object_orientation']))
-        return item
\ No newline at end of file
diff --git a/CyXTraX/data/__init__.py b/CyXTraX/data/__init__.py
deleted file mode 100644
index b1d77652b80039a747b78e562d39d0e61c56a704..0000000000000000000000000000000000000000
--- a/CyXTraX/data/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import importlib.resources
-import numpy as np
-from ..common import MeshObject
-
-
-with importlib.resources.path('CyXTraX.data', 'olaf_6.stl') as file_path:
-    olaf_stl = file_path
-    olaf_mesh = MeshObject(olaf_stl, 
-                           position_mm=np.array([1, 2, 3]),
-                           orientation_quat=np.array([0., 0., 0., 1.]))
-    
-with importlib.resources.path('CyXTraX.data', 'scones.stl') as file_path:
-    scones_stl = file_path
-    scones_mesh = MeshObject(scones_stl, 
-                             position_mm=np.array([0, 0, 0]),
-                             orientation_quat=np.array([0., 0., 0., 1.]))
\ No newline at end of file
diff --git a/CyXTraX/io/__init__.py b/CyXTraX/io/__init__.py
deleted file mode 100644
index 7ba211c6e3a0ef115cdd387bd8d8b4d82e7766b8..0000000000000000000000000000000000000000
--- a/CyXTraX/io/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .generate_atlas import record_atlas
-from .load_maps import load_atlas
\ No newline at end of file
diff --git a/CyXTraX/io/generate_atlas.py b/CyXTraX/io/generate_atlas.py
deleted file mode 100644
index 1df4b4fa98a68112e744c51af86a08ab2dae6808..0000000000000000000000000000000000000000
--- a/CyXTraX/io/generate_atlas.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import numpy as np
-import h5py
-from CyXTraX.simulation.artist_bridge import CylindricalProjection
-from CyXTraX.common.mesh_object import MeshObject
-from pathlib import Path
-import json
-
-
-
-def to_dict(mesh_object = MeshObject) -> dict:
-    return mesh_object.as_dict()
-
-
-def record_atlas(cylindrical_projection: CylindricalProjection, mesh_list: list[MeshObject], 
-                atlas_name: str, save_folder: Path,
-                map_bounding_box: tuple[float]=(-50., 50.), number_of_maps: int = 4) -> Path:
-    
-    grid = np.linspace(map_bounding_box[0], map_bounding_box[1], number_of_maps)
-    file_index = len(list(save_folder.glob('*.h5')))+1
-    save_path = save_folder / f'{file_index:05}_{atlas_name}.h5'
-    file = h5py.File(save_path, 'a')
-    projection = file.require_dataset(
-        'maps', 
-        shape=(cylindrical_projection.x_px, cylindrical_projection.y_px, number_of_maps**3),  # Initial shape with third dimension as 0
-        maxshape=(cylindrical_projection.x_px, cylindrical_projection.y_px, number_of_maps**3), 
-        dtype=np.float32)
-
-    projection_points = file.require_dataset(
-        'positions', 
-        shape=(3, number_of_maps**3),  # Initial shape with third dimension as 0
-        maxshape=(3, number_of_maps**3), 
-        dtype=np.float32)
-    
-
-    mesh_list_dict = list(map(to_dict, mesh_list))
-    print(mesh_list_dict)
-    
-    file.attrs['mesh_list'] = json.dumps(mesh_list_dict)
-
-    
-    counter = 0
-    for x in grid:
-        for y in grid:
-            for z in grid:
-                # x, y, z = 0, y, 0
-                print(x, y, z)
-                position = np.array([x, y, z])
-                
-                image = cylindrical_projection.compute_projection(position, output_full_ray_projection=True)
-                current_size = projection.shape[2]
-                new_size = current_size + 1
-                #projection.resize((cylindrical_projection.x_px, cylindrical_projection.y_px, new_size))
-                projection[:, :, counter:counter+1] = image[:, :, np.newaxis].astype(np.float32)
-
-                #projection_points.resize((3, new_size))
-                projection_points[:, counter:counter+1] = position.reshape((3, 1))
-                counter += 1
-    return save_path
diff --git a/CyXTraX/mapping/__init__.py b/CyXTraX/mapping/__init__.py
deleted file mode 100644
index 05cdb726d7dbc2a5899169dddc14c2db8c1b25e8..0000000000000000000000000000000000000000
--- a/CyXTraX/mapping/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .mapping import map_geometry_2_projection, map_source_2_cylinder
\ No newline at end of file
diff --git a/CyXTraX/mapping/mapping.py b/CyXTraX/mapping/mapping.py
deleted file mode 100644
index 8a153a69e65c86030a7c36520d408e8940f761d6..0000000000000000000000000000000000000000
--- a/CyXTraX/mapping/mapping.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from jax import numpy as jnp
-import dm_pix as pix
-from jax import jit, vmap
-from jax.scipy.spatial.transform import Rotation
-
-
-
-@jit
-def map_source_2_cylinder(source: jnp.ndarray, maps: jnp.ndarray, map_positions: jnp.ndarray, radius: float = 1000.,
-                          angle_discretisation: int = 2000, pitch: float = jnp.pi) -> tuple[jnp.ndarray, jnp.ndarray]:
-    """
-    source:        1 x 3
-    maps:          u x v x m
-    map_positions:     3 x m 
-
-    ---
-
-    cylinder_value:        m x 1
-    """
-
-    #map_positions = map_positions.T # m x 3
-
-    angles = cylindrical_angles(source, map_positions, radius, angle_discretisation, pitch)
-
-    u = jnp.expand_dims(angles[0], 0) # 1 x m
-    v = jnp.expand_dims(angles[1], 0) # 1 x m
-    w = jnp.arange(0, maps.shape[2])[jnp.newaxis, ...] #+0.0001 # 1 x m
-
-    uvw = jnp.concatenate([v, u , w], 0) # 3 x m
-    values = pix.flat_nd_linear_interpolate(maps, uvw)
-
-
-    return values, uvw # m,
-
-@jit
-def cylindrical_angles(source: jnp.ndarray, map_positions: jnp.ndarray, radius: float = 1000.,
-                       angle_discretisation: int = 2000, pitch: float = jnp.pi) -> tuple[jnp.ndarray, jnp.ndarray]:
-    source = source.reshape((-1, 1)) # 1 x 3
-    directions =  map_positions - source # m x 3
-    direction_norm_factor = jnp.linalg.norm(directions[:2], axis=0, keepdims=True)
-    directions = directions / direction_norm_factor  # m x 3
-    intersection = directions * radius
-    # sign = jnp.where(intersection[2]>=0, 1, -1)
-    # intersection = intersection * sign
-    
-    
-    z_value = intersection[2] / pitch
-    z = z_value + (angle_discretisation) / 2.
-    beta_value = (jnp.arctan2(intersection[0], intersection[1]) / jnp.pi) * angle_discretisation / 2
-    beta = beta_value - ((angle_discretisation - 1.) / 4.)
-    angles = jnp.concatenate(
-        (jnp.expand_dims(z, 0) % 2000,
-         jnp.expand_dims(beta, 0) % 2000), 
-        axis=0)
-    return angles
-
-
-@jit
-def map_geometry_2_projection(source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray, 
-                              map_positions: jnp.ndarray,
-                              projections: jnp.ndarray, pixel_pitch_mm: float = 0.139):
-    """
-    source:               1 x 3
-    detector:             1 x 3
-    detector_orientation: 1 x 4
-    map_positions:            3 x m
-    projections:                  u x v
-    pixel_pitch_mm:               1,
-
-    ---
-
-    projection_value:             m
-    """
-    source = source.reshape((1, 3))
-    detector = detector.reshape((1, 3))
-    detector_orientation = detector_orientation.reshape((1, 4))
-
-
-    projection_geometry = projection_matrix(source, detector, detector_orientation) # 3 x 4
-    map_positions_homogen = jnp.ones((1, map_positions.shape[1])) # 1 x m
-    map_positions_homogen = jnp.concatenate((map_positions, map_positions_homogen), 0) # 4 x m
-    uv_px = projection_geometry @ map_positions_homogen # 3 x m
-    uv_px = uv_px / uv_px[2]
-    uv_px = uv_px / pixel_pitch_mm
-    uv_px = uv_px.at[0,:].multiply(-1)
-    uv_px = uv_px.at[0,:].add((projections.shape[-2])/ 2.)
-    # uv_px = uv_px.at[0,:].multiply(-1)
-    uv_px = uv_px.at[1,:].add((projections.shape[-2])/ 2.)
-    uv_px = uv_px[:2]
-
-    uv_px_flip = jnp.flip(uv_px, 0)
-    # uv_px_flip = uv_px
-   
-    return pix.flat_nd_linear_interpolate(projections, uv_px_flip), uv_px
-
-
-@jit
-def projection_matrix(source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray
-    ) -> jnp.ndarray:
-    """
-    source:               1 x 3
-    detector:             1 x 3
-    detector_orientation: 1 x 4
-
-    ---
-
-    projection_matrix =   3 x 4
-    """
-    detector_orientation = detector_orientation / detector_orientation[1, 3]
-    rotation_matrix = Rotation.from_quat(detector_orientation).as_matrix()
-    detector_horizontal_vector = -rotation_matrix[0, :, 0]
-    detector_vertical_vector = -rotation_matrix[0, :, 1]
-    p3x3 = jnp.vstack([detector_horizontal_vector, 
-                       detector_vertical_vector,
-                       (detector - source).reshape((-1, 3))]).T
-    p3x3_inv = jnp.linalg.inv(p3x3)
-    p4 = p3x3_inv @ (-source).reshape((3, 1))
-    matrix = jnp.concatenate([p3x3_inv, p4], 1) # 3 x 4
-    return matrix
\ No newline at end of file
diff --git a/CyXTraX/simulation/__init__.py b/CyXTraX/simulation/__init__.py
deleted file mode 100644
index 320873fc56954f7ef06fb39d6212e32369f54dc5..0000000000000000000000000000000000000000
--- a/CyXTraX/simulation/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .artist_bridge import CylindricalProjection, load_mesh, SAVEMODES, utility
\ No newline at end of file
diff --git a/CyXTraX/simulation/model/__init__.py b/CyXTraX/simulation/model/__init__.py
deleted file mode 100644
index ab04eac9c5d8225922a1310bae4c74e804e57956..0000000000000000000000000000000000000000
--- a/CyXTraX/simulation/model/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-
-from .augemtation_parameters import AugemntationParameter
-from .noise import add_white_noise, add_gaussian_blur
-from .xray import add_material
\ No newline at end of file
diff --git a/CyXTraX/util/datasets/__init__.py b/CyXTraX/util/datasets/__init__.py
deleted file mode 100644
index 4a6739ff541d5191c1180f930897dff03e6b0b18..0000000000000000000000000000000000000000
--- a/CyXTraX/util/datasets/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .merge import merge_atlas_and_dict, merge_atlases, merge_lists
-from .pipeline import generate_atlas_from_folder
\ No newline at end of file
diff --git a/CyXTraX/util/datasets/merge.py b/CyXTraX/util/datasets/merge.py
deleted file mode 100644
index d1aae3f372d05fe00d83f006bdf9508e8a40eecb..0000000000000000000000000000000000000000
--- a/CyXTraX/util/datasets/merge.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from jax import numpy as jnp
-from CyXTraX.common.mesh_object import MeshObject
-
-
-def merge_atlases(carry_atlas: jnp.ndarray, atlas: jnp.ndarray) -> jnp.ndarray:
-    return carry_atlas.at[:].add(atlas) / 2.
-
-
-def merge_lists(carry_list: list, x: list) -> list:
-    return carry_list.extend(x)
-
-
-def merge_atlas_and_dict(atlas_one, mesh_list_one, atlas_two, mesh_list_two) -> tuple[jnp.ndarray, list]:
-    return merge_atlases(atlas_one, atlas_two), merge_lists(mesh_list_one, mesh_list_two)
diff --git a/CyXTraX/util/visualisation/__init__.py b/CyXTraX/util/visualisation/__init__.py
deleted file mode 100644
index 589931f1beaaf10328afcd4cafd2efc5dbbd40c0..0000000000000000000000000000000000000000
--- a/CyXTraX/util/visualisation/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .plt import save_map_plot_with_index, voxel_cone_maps
-from .gif import make_gif
\ No newline at end of file
diff --git a/README.md b/README.md
index ceb674e2a9791581f475d5e06bccdf9b22a860c1..f102b30f9aa5766ae046b8fb5b0b53bba269e4fa 100644
--- a/README.md
+++ b/README.md
@@ -13,3 +13,58 @@ The local cylindrical xray transform maps are stored as `.h5` file.
 
 
 
+## Examples
+Example files are from the `scripts` folder and directly included and updated via [CODE-EMBEDDER](https://github.com/kvankova/code-embedder).
+
+### Generate a Cylindrical Projection
+
+```python:../scripts/01_aRTist_bridge.py:s:A
+    # Create the cylindrical projection interface
+    cyl_proj = CylindricalProjection()
+
+
+    # Load the test object 'olaf'. It is automatically installed to your site-packages
+    print(f'STL Path: {scones_mesh.object_path}')
+
+    # Obect are loaded in a dataclass: MeshObject.
+    print(f'Mesh is a MeshObject: {isinstance(scones_mesh, MeshObject)}')
+    scones_mesh.position_mm = np.array([0, 0, 0])
+    scones_mesh.orientation_quat = np.array([0., -0., 0., 0.1])
+    
+    
+    # The `load_mesh` function load a list of MeshObject
+    load_mesh(cyl_proj, [scones_mesh])
+
+    # Set local position of cylindrical projection
+    map_position = np.array([0, 0, 0])
+
+    # Generate local cylindrical projection
+    half_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=False)
+    full_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=True)
+```
+
+![](./temp/scones.png)
+
+### Generate a Cylindrical Projection Atlas
+
+```python:../scripts/02_generate_atlas.py:s:A
+    # Create the cylindrical projection interface
+    cyl_proj = CylindricalProjection()
+    load_mesh(cyl_proj, [olaf_mesh])
+    # make an atlas
+    
+    save_path = record_atlas(cyl_proj, [olaf_mesh], 'test', TEMP_FOLDER, 
+                            map_bounding_box=[-10, 20], number_of_maps=2)
+```
+
+### Load Atlas
+
+```python:../scripts/03_load_atlas.py:s:A
+    files = list(TEMP_FOLDER.glob('*.h5'))
+    if not files:
+        raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!')
+
+    maps, points, mesh_object_list = load_atlas(files[-1])
+``` 
+
+![](./temp/scones_maps.png)
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..91b03059a663904a9640f16aaa0063e2b555978e
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,35 @@
+[project]
+name = "cyxtrax"
+version = "0.1.0"
+description = "Add your description here"
+readme = "README.md"
+authors = [
+    { name = "swittl", email = "simon.wittl@th-deg.de" }
+]
+requires-python = ">=3.10"
+dependencies = [
+    "artistlib",
+    "dm-pix>=0.4.3",
+    "h5py>=3.12.1",
+    "jax>=0.4.35 ; sys_platform == 'windows'",
+    "jax[cuda12]>=0.4.35 ; sys_platform == 'linux'",
+    "matplotlib>=3.9.2",
+    "numpy>=2.1.3",
+    "ruff>=0.7.3",
+    "scipy>=1.14.1",
+    "xraylib>=4.1.5",
+]
+
+
+[tool.uv.sources]
+artistlib = { git = "https://github.com/wittlsn/aRTist-PythonLib" }
+cyxtrax = { workspace = true }
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.ruff]
+exclude = [
+    ".venv",
+]
diff --git a/scripts/01_aRTist_bridge.py b/scripts/01_aRTist_bridge.py
index ff40e914eec7ff53c8f8ba007931fe6f3c0f6789..2d93de9ed2a942eca9d6c6b1a6d6d00e61f118b4 100644
--- a/scripts/01_aRTist_bridge.py
+++ b/scripts/01_aRTist_bridge.py
@@ -1,6 +1,6 @@
-from CyXTraX.simulation import CylindricalProjection, load_mesh
-from CyXTraX.data import scones_mesh
-from CyXTraX.common import MeshObject
+from cyxtrax.simulation import CylindricalProjection, load_mesh
+from cyxtrax.data import scones_mesh
+from cyxtrax.common import MeshObject
 
 import numpy as np
 from matplotlib import pyplot as plt
@@ -12,6 +12,7 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp'
 
 
 def main():
+    # code_embedder:A start
     # Create the cylindrical projection interface
     cyl_proj = CylindricalProjection()
 
@@ -33,11 +34,8 @@ def main():
 
     # Generate local cylindrical projection
     half_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=False)
-    # output_full_ray_projection=True is the same As 
-    # half_rays = cyl_proj.compute_projection(position, output_full_ray_projection=False)
-    # full_rays = cyl_proj.convert_rays(half_rays)
     full_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=True)
-    
+    # code_embedder:A end
 
     # Make some nice plots!
     fig = plt.figure(figsize=(12, 6))
diff --git a/scripts/02_generate_atlas.py b/scripts/02_generate_atlas.py
index 39eff9da2c39deaa088f45e2cdc4dd1d30c18fe9..c6394023741d8f3527bc10f1c65885ac64e2fc09 100644
--- a/scripts/02_generate_atlas.py
+++ b/scripts/02_generate_atlas.py
@@ -10,6 +10,7 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp'
 
 
 def main():
+    # code_embedder:A start
     # Create the cylindrical projection interface
     cyl_proj = CylindricalProjection()
     load_mesh(cyl_proj, [olaf_mesh])
@@ -17,8 +18,9 @@ def main():
     
     save_path = record_atlas(cyl_proj, [olaf_mesh], 'test', TEMP_FOLDER, 
                             map_bounding_box=[-10, 20], number_of_maps=2)
+    # code_embedder:A end
     print(f'Atlas saved to the path: {save_path}')
-
+    
     
 
 if __name__ == '__main__':
diff --git a/scripts/03_load_atlas.py b/scripts/03_load_atlas.py
index b574781233ee98e68074bcf5ddfaff408e38753c..f20a8afcc7ce574865d2a7e765e171a003bdb044 100644
--- a/scripts/03_load_atlas.py
+++ b/scripts/03_load_atlas.py
@@ -1,4 +1,5 @@
-from CyXTraX.io import load_atlas
+from cyxtrax.io import load_atlas
+from cyxtrax.util.visualisation import voxel_maps
 from pathlib import Path
 
 
@@ -8,16 +9,18 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp'
 
 
 def main():
+    # code_embedder:A start
     files = list(TEMP_FOLDER.glob('*.h5'))
     if not files:
         raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!')
 
     maps, points, mesh_object_list = load_atlas(files[-1])
-    
+    # code_embedder:A end
     print(f'Loaded Map Shape: {maps.shape}')
     print(f'Loaded Map Centre Shape: {points.shape}')
     print(f'First Object: {mesh_object_list[0]}')
-    
+
+    voxel_maps(maps, TEMP_FOLDER / 'scones_maps.png', title='Scones Atlas')
 
 if __name__ == '__main__':
     main()
\ No newline at end of file
diff --git a/scripts/04_mapping.py b/scripts/04_mapping.py
index 45f729becf805b33ba531a58e094c20bab3e620b..175ca9d2c5bd368bd5edcf00870d35c70bf21f97 100644
--- a/scripts/04_mapping.py
+++ b/scripts/04_mapping.py
@@ -8,100 +8,107 @@ from matplotlib import pyplot as plt, figure
 
 
 # Just get the temp folder to store the atlas
-FOLDER = Path(__file__)
-TEMP_FOLDER = FOLDER.parent.parent / 'temp'
+FOLDER = Path("/mnt/data/xray_studies_data/")
+TEMP_FOLDER = FOLDER / "dataset_64"
 
 
 def main():
-    files = list(TEMP_FOLDER.glob('*.h5'))
+    files = list(TEMP_FOLDER.glob("*.h5"))
     if not files:
-        raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!')
+        raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!")
 
     maps, points, mesh_object_list = load_atlas(files[-1])
     cyl_proj = CylindricalProjection()
-    
+
     load_mesh(cyl_proj, mesh_object_list, False)
-    print(f'Cone Beam Mode set: {cyl_proj.cone_mode}')
+    print(f"Cone Beam Mode set: {cyl_proj.cone_mode}")
 
     rot = 30
     x, y = 2000 * jnp.cos(rot * jnp.pi / 180), 500 * jnp.sin(rot * jnp.pi / 180)
-    source_position = jnp.array([x, y, 0.]).reshape((1, 3))
-    detector_position = jnp.array([-x, -y, -10.]).reshape((1, 3))
-    detctor_orientation_scipy = Rotation.from_euler('xyz', [0, -90, rot], degrees=True)
+    source_position = jnp.array([x, y, 0.0]).reshape((1, 3))
+    detector_position = jnp.array([-x, -y, -10.0]).reshape((1, 3))
+    detctor_orientation_scipy = Rotation.from_euler("xyz", [0, -90, rot], degrees=True)
 
-    temp_projection = Path('temp.tif')
+    temp_projection = Path("temp.tif")
     detctor_orientation = detctor_orientation_scipy.as_quat().reshape((1, -1))
 
-    cyl_proj.api.translate('S', source_position[0, 0], source_position[0, 1], source_position[0, 2])
-    cyl_proj.api.translate('D', detector_position[0, 0], detector_position[0, 1], detector_position[0, 2])
-    cyl_proj.api.rotate_from_quat('D', detctor_orientation[0])
+    cyl_proj.api.translate(
+        "S", source_position[0, 0], source_position[0, 1], source_position[0, 2]
+    )
+    cyl_proj.api.translate(
+        "D", detector_position[0, 0], detector_position[0, 1], detector_position[0, 2]
+    )
+    cyl_proj.api.rotate_from_quat("D", detctor_orientation[0])
     cyl_proj.api.save_image(temp_projection, save_mode=SAVEMODES.FLOAT_TIFF)
 
     projection, geometry = utility.load_projection(temp_projection)
 
     mapped_values, uv_px = map_geometry_2_projection(
-            source_position, 
-            detector_position,
-            detctor_orientation,
-            points,
-            projection, 
-            cyl_proj.pixel_pitch_mm)
-        
+        source_position,
+        detector_position,
+        detctor_orientation,
+        points,
+        projection,
+        cyl_proj.pixel_pitch_mm,
+    )
+
     values_calc, angles_calc = map_source_2_cylinder(
-        source_position, 
-        maps, 
-        points, 
-        cyl_proj.detector_radius_mm, 
+        source_position,
+        maps,
+        points,
+        cyl_proj.detector_radius_mm,
         cyl_proj.x_px,
-        cyl_proj.x_resolution_mm)
-    
-    for i in range(values_calc.shape[0]):
-        print(f'Step {i}: Value Cylinder {values_calc[i]:2.2f} \t/\t Value Projection {mapped_values[i]:2.2f}')
+        cyl_proj.x_resolution_mm,
+    )
 
+    for i in range(values_calc.shape[0]):
+        print(
+            f"Step {i}: Value Cylinder {values_calc[i]:2.2f} \t/\t Value Projection {mapped_values[i]:2.2f}"
+        )
 
     fig = plt.figure(figsize=(24, 10))
     subfig1: figure.Figure
     subfig2: figure.Figure
     subfig1, subfig2 = fig.subfigures(1, 2)
     ax1 = subfig1.add_subplot(111)
-    ax1.set_title('Projection Mapping')
+    ax1.set_title("Projection Mapping")
     im = ax1.imshow(projection, vmin=maps.min(), vmax=maps.max())
 
     counter = 0
     number_of_maps = maps.shape[2]
 
     color = jnp.linspace(0, 1, 9)[:number_of_maps]
-    cmap = plt.get_cmap('hsv')
+    cmap = plt.get_cmap("hsv")
     colors = cmap(color)
     ax1.scatter(uv_px[0, :9], uv_px[1, :9], c=colors)
-    ax1.set_xlabel(r'$u$ / px')
-    ax1.set_ylabel(r'$v$ / px')
-    subfig1.colorbar(im, ax=ax1, orientation='vertical', label='Ray Length / mm')
+    ax1.set_xlabel(r"$u$ / px")
+    ax1.set_ylabel(r"$v$ / px")
+    subfig1.colorbar(im, ax=ax1, orientation="vertical", label="Ray Length / mm")
 
-    
     ax2 = subfig2.add_subplot(111)
-    ax2.set_title('Cylindrical Mapping')
+    ax2.set_title("Cylindrical Mapping")
     ax2.axis(False)
     for _ in range(3):
         for _ in range(3):
             if counter >= number_of_maps:
                 continue
-            ax = subfig2.add_subplot(3, 3, counter+1)
+            ax = subfig2.add_subplot(3, 3, counter + 1)
             ax.imshow(maps[:, :, counter], vmin=maps.min(), vmax=maps.max())
-            ax.scatter(angles_calc[0, counter], angles_calc[1, counter],  c=colors[counter])
-            ax.set_xlabel(r'$z$ / mm')
-            ax.set_ylabel(r'$\alpha$ / rad')
-            ax.set_xticks([0, 1000, 2000]) 
-            ax.set_xticklabels([r'$-3141.5$', r'$0.$',  r'$3141.5$']) 
-            ax.set_yticks([0, 1000, 2000]) 
-            ax.set_yticklabels([r'$-\pi$', r'$0.$',  r'$\pi$']) 
+            ax.scatter(
+                angles_calc[0, counter], angles_calc[1, counter], c=colors[counter]
+            )
+            ax.set_xlabel(r"$z$ / mm")
+            ax.set_ylabel(r"$\alpha$ / rad")
+            ax.set_xticks([0, 1000, 2000])
+            ax.set_xticklabels([r"$-3141.5$", r"$0.$", r"$3141.5$"])
+            ax.set_yticks([0, 1000, 2000])
+            ax.set_yticklabels([r"$-\pi$", r"$0.$", r"$\pi$"])
 
             counter += 1
 
     plt.tight_layout()
-    plt.savefig(TEMP_FOLDER / 'mapping.png')
+    plt.savefig(TEMP_FOLDER / "mapping.png")
 
-    
 
-if __name__ == '__main__':
-    main()
\ No newline at end of file
+if __name__ == "__main__":
+    main()
diff --git a/scripts/05_data_augmentation.py b/scripts/05_data_augmentation.py
index 2ab1212390e0e98ebb6704dd8e455c87f8e8b928..81741745d9b7b6968dd38abead5756d52a34ef53 100644
--- a/scripts/05_data_augmentation.py
+++ b/scripts/05_data_augmentation.py
@@ -8,42 +8,61 @@ from jax import random
 
 
 # Just get the temp folder to store the atlas
-FOLDER = Path(__file__)
-TEMP_FOLDER = FOLDER.parent.parent / 'temp'
+FOLDER = Path("/mnt/data/xray_studies_data/")
+TEMP_FOLDER = FOLDER / "dataset_64"
 
 
 def main():
-    files = list(TEMP_FOLDER.glob('*.h5'))
+    files = list(TEMP_FOLDER.glob("*.h5"))
     if not files:
-        raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!')
+        raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!")
 
     map_index = 3
     maps, points, mesh_object_list = load_atlas(files[-1])
     random_key = random.PRNGKey(42)
-    save_map_plot_with_index(maps, map_index, TEMP_FOLDER / 'blank_map.png')
+    save_map_plot_with_index(maps, map_index, TEMP_FOLDER / "blank_map.png")
 
-    map_with_white_noise, white_noise_parameter, random_key = add_white_noise(maps, 5.3, 10.1, random_key)
+    map_with_white_noise, white_noise_parameter, random_key = add_white_noise(
+        maps, 5.3, 10.1, random_key
+    )
     print(white_noise_parameter)
     save_map_plot_with_index(
-        map_with_white_noise, map_index, TEMP_FOLDER / 'noise_map.png',
-        title='White Noise')
+        map_with_white_noise,
+        map_index,
+        TEMP_FOLDER / "noise_map.png",
+        title="White Noise",
+    )
 
-    map_with_gaussian_blur, gaussian_blur_parameter, random_key = add_gaussian_blur(maps, 1.1, 3, random_key)
+    map_with_gaussian_blur, gaussian_blur_parameter, random_key = add_gaussian_blur(
+        maps, 1.1, 3, random_key
+    )
     print(gaussian_blur_parameter)
     save_map_plot_with_index(
-        map_with_gaussian_blur, map_index, TEMP_FOLDER / 'gaussian_map.png',
-        title='Gaussian Blur')
-    
-    map_with_attenuation, attenuation_parameter, random_key = add_material(maps, 'c', 225, 30, random_key)
+        map_with_gaussian_blur,
+        map_index,
+        TEMP_FOLDER / "gaussian_map.png",
+        title="Gaussian Blur",
+    )
+
+    map_with_attenuation, attenuation_parameter, random_key = add_material(
+        maps, "c", 225, 30, random_key
+    )
     print(attenuation_parameter)
     save_map_plot_with_index(
-        map_with_attenuation, map_index, TEMP_FOLDER / 'attenuation_c_map.png',
-        title='Attenuation C')
-    
+        map_with_attenuation,
+        map_index,
+        TEMP_FOLDER / "attenuation_c_map.png",
+        title="Attenuation C",
+    )
+
     merged_map = merge_atlases(map_with_gaussian_blur, map_with_white_noise)
     save_map_plot_with_index(
-        merged_map, map_index, TEMP_FOLDER / 'merged_map.png',
-        title='Merged Map: Gaussian + Noise')
+        merged_map,
+        map_index,
+        TEMP_FOLDER / "merged_map.png",
+        title="Merged Map: Gaussian + Noise",
+    )
+
 
-if __name__ == '__main__':
-    main()
\ No newline at end of file
+if __name__ == "__main__":
+    main()
diff --git a/scripts/06_generate_dataset.py b/scripts/06_generate_dataset.py
index 79f8dc400b01d975a510c06a29ad65664650d2b3..224df5e0680195688360a51acd1f3810b59a5036 100644
--- a/scripts/06_generate_dataset.py
+++ b/scripts/06_generate_dataset.py
@@ -9,23 +9,29 @@ It takes about 300 minutes of time
 and needs 100gb of space.
 """
 
+
 def main():
     # Dataset save folder
-    save_folder = Path(r'\\192.168.43.8\data\Wittl\06_datasets\XrayTransform')
+    save_folder = Path(r"\\192.168.43.8\data\Wittl\06_datasets\XrayTransform")
     number_of_maps = 4
     map_bounding_box = 25
     # Dataset of multiple random stl files from: https://ten-thousand-models.appspot.com/
-    load_folder = Path(r'C:\Users\swittl\Downloads\Thingi10K\Thingi10K\raw_meshes')
-    
-    number_of_samples = len(list(save_folder.glob('*.h5'))) + 1
-    
+    load_folder = Path(r"C:\Users\swittl\Downloads\Thingi10K\Thingi10K\raw_meshes")
+
+    number_of_samples = len(list(save_folder.glob("*.h5"))) + 1
+
     for i in range(number_of_samples, number_of_samples + 100):
         # start from number of samples to generate diffrent rng keys!!!
         print(i)
-        key = random.PRNGKey(i)    
+        key = random.PRNGKey(i)
         generate_atlas_from_folder(
-            load_folder, key, save_folder, map_bounding_box=(-map_bounding_box, map_bounding_box), number_of_maps=number_of_maps)
-    
+            load_folder,
+            key,
+            save_folder,
+            map_bounding_box=(-map_bounding_box, map_bounding_box),
+            number_of_maps=number_of_maps,
+        )
+
 
-if __name__ == '__main__':
-    main()
\ No newline at end of file
+if __name__ == "__main__":
+    main()
diff --git a/scripts/07_presentation.py b/scripts/07_presentation.py
index 8540a44f317729c9f73b17f65db0551ab28eb8cc..bc834f6cc50649169ad2c0c8946eeb5fbfd2d384 100644
--- a/scripts/07_presentation.py
+++ b/scripts/07_presentation.py
@@ -1,71 +1,105 @@
-from CyXTraX.simulation import CylindricalProjection, load_mesh, SAVEMODES, utility
+from CyXTraX.simulation import CylindricalProjection, load_mesh, utility
 from CyXTraX.io import load_atlas
 from CyXTraX.mapping import map_geometry_2_projection, map_source_2_cylinder
 from CyXTraX.util.visualisation import voxel_cone_maps
 
 from pathlib import Path
 from jax import numpy as jnp
-from jax.scipy.spatial.transform import Rotation
-
-from cyxtrax_object import set_geometry_at_index, circular_trajectory, add_world_orign, zero_quat, x_90_quat, z_90_quat, add_offset
 
+from cyxtrax_object import (
+    set_geometry_at_index,
+    circular_trajectory,
+    add_world_orign,
+    zero_quat,
+    add_offset,
+)
 
 
 # Just get the temp folder to store the atlas
 FOLDER = Path(__file__)
-TEMP_FOLDER = FOLDER.parent.parent / 'temp'
-MAP_FOLDER = Path(r'C:\data\XrayTransformLow')
+TEMP_FOLDER = FOLDER.parent.parent / "temp"
+MAP_FOLDER = Path(r"C:\data\XrayTransformLow")
 
 
 def main():
-    files = list(MAP_FOLDER.glob('*.h5'))
+    files = list(MAP_FOLDER.glob("*.h5"))
     if not files:
-        raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!')
+        raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!")
 
     maps, points, mesh_object_list = load_atlas(files[3])
     cyl_proj = CylindricalProjection()
-    
-    load_mesh(cyl_proj, mesh_object_list, False)
-    print(f'Cone Beam Mode set: {cyl_proj.cone_mode}')
 
+    load_mesh(cyl_proj, mesh_object_list, False)
+    print(f"Cone Beam Mode set: {cyl_proj.cone_mode}")
 
     number_of_projections = 30
 
-    fod_mm = jnp.array([1000,])
-    fdd_mm = jnp.array([2000,])
+    fod_mm = jnp.array(
+        [
+            1000,
+        ]
+    )
+    fdd_mm = jnp.array(
+        [
+            2000,
+        ]
+    )
     alpha_rad = jnp.linspace(0, jnp.pi, number_of_projections).reshape((-1, 1))
 
-    source, orientation_source, detector, orientation_detector = circular_trajectory(fod_mm, fdd_mm, alpha_rad)
+    source, orientation_source, detector, orientation_detector = circular_trajectory(
+        fod_mm, fdd_mm, alpha_rad
+    )
     source, orientation_source, detector, orientation_detector = add_world_orign(
-        source, orientation_source, detector, orientation_detector, jnp.array([1, 2., -1.]), jnp.array([0.8, 0.1, -0.1, 0.9]))
-    detector, orientation_detector = add_offset(detector, orientation_detector, jnp.array([1, 20., -1.]), zero_quat)
-
-    temp_projection = Path('temp.tif')
-    
+        source,
+        orientation_source,
+        detector,
+        orientation_detector,
+        jnp.array([1, 2.0, -1.0]),
+        jnp.array([0.8, 0.1, -0.1, 0.9]),
+    )
+    detector, orientation_detector = add_offset(
+        detector, orientation_detector, jnp.array([1, 20.0, -1.0]), zero_quat
+    )
+
+    temp_projection = Path("temp.tif")
 
-    
     for i in range(number_of_projections):
-        set_geometry_at_index(source, orientation_source, detector, orientation_detector, i, temp_projection)
+        set_geometry_at_index(
+            source,
+            orientation_source,
+            detector,
+            orientation_detector,
+            i,
+            temp_projection,
+        )
 
         projection, geometry = utility.load_projection(temp_projection)
         mapped_values, uv_px = map_geometry_2_projection(
-                source[i], 
-                detector[i],
-                orientation_detector[i],
-                points,
-                projection, 
-                cyl_proj.pixel_pitch_mm)
-            
+            source[i],
+            detector[i],
+            orientation_detector[i],
+            points,
+            projection,
+            cyl_proj.pixel_pitch_mm,
+        )
+
         values_calc, angles_calc = map_source_2_cylinder(
-            source[i], 
-            maps, 
-            points, 
-            cyl_proj.detector_radius_mm, 
+            source[i],
+            maps,
+            points,
+            cyl_proj.detector_radius_mm,
             cyl_proj.x_px,
-            cyl_proj.x_resolution_mm)
-        
-        voxel_cone_maps(maps, projection, uv_px, angles_calc, TEMP_FOLDER / f'{i:03}_presentation.png')
-    
+            cyl_proj.x_resolution_mm,
+        )
+
+        voxel_cone_maps(
+            maps,
+            projection,
+            uv_px,
+            angles_calc,
+            TEMP_FOLDER / f"{i:03}_presentation.png",
+        )
+
 
-if __name__ == '__main__':
-    main()
\ No newline at end of file
+if __name__ == "__main__":
+    main()
diff --git a/scripts/08_make_gif.py b/scripts/08_make_gif.py
index 2498d0c90a3219b37f04f22ad18a0286babbc283..e1eac1da5bae14d1994b347742086138eb76d0be 100644
--- a/scripts/08_make_gif.py
+++ b/scripts/08_make_gif.py
@@ -3,11 +3,12 @@ from pathlib import Path
 
 # Just get the temp folder to store the atlas
 FOLDER = Path(__file__)
-TEMP_FOLDER = FOLDER.parent.parent / 'temp'
+TEMP_FOLDER = FOLDER.parent.parent / "temp"
+
 
 def main():
-    make_gif(TEMP_FOLDER, '*_presentation.png', 'cyxtrax.gif', 333)
+    make_gif(TEMP_FOLDER, "*_presentation.png", "cyxtrax.gif", 333)
 
 
-if __name__ == '__main__':
-    main()
\ No newline at end of file
+if __name__ == "__main__":
+    main()
diff --git a/CyXTraX/__init__.py b/scripts/09_data_aug_pipeline.py
similarity index 100%
rename from CyXTraX/__init__.py
rename to scripts/09_data_aug_pipeline.py
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 35504c4d4e5228ec6b13944887cd726eca713dc8..0000000000000000000000000000000000000000
--- a/setup.cfg
+++ /dev/null
@@ -1,28 +0,0 @@
-[metadata]
-name = CyXTraX
-version = 0.1.0
-description = A Python module to play with local cylindrical xray transform maps or atlases.
-author = Simon Wittl
-author_email = simon.wittl@th-deg.de / simonwittl@gmail.com
-url = https://mygit.th-deg.de/roboct/xraytrafo
-
-[options]
-packages = find:
-include_package_data = True  # Ensures data files are included
-zip_safe = False
-
-[options.package_data]
-CyXTraX = 
-    data/cone.aRTist
-    data/cylinder.aRTist
-    data/olaf_6.stl
-    data/scones.stl
-
-install_requires =
-    numpy>=2.0.0
-    jaxlib
-    jax
-    git+https://github.com/wittlsn/aRTist-PythonLib
-    scipy
-    dm_pix
-    xraylib
\ No newline at end of file
diff --git a/setup.py b/setup.py
deleted file mode 100644
index fc1f76c84d17b458f7090667d495592c9abda034..0000000000000000000000000000000000000000
--- a/setup.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from setuptools import setup
-
-setup()
\ No newline at end of file
diff --git a/CyXTraX/util/__init__.py b/src/cyxtrax/__init__.py
similarity index 100%
rename from CyXTraX/util/__init__.py
rename to src/cyxtrax/__init__.py
diff --git a/src/cyxtrax/common/__init__.py b/src/cyxtrax/common/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7c315e4bdfc523b5f0b0ecc157a3dcc366044e11
--- /dev/null
+++ b/src/cyxtrax/common/__init__.py
@@ -0,0 +1,6 @@
+from .mesh_object import MeshObject
+
+
+__all__ = [
+    'MeshObject'
+]
\ No newline at end of file
diff --git a/src/cyxtrax/common/mesh_object.py b/src/cyxtrax/common/mesh_object.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee43ca348d1daad1fc3953f03fb80922ea43a413
--- /dev/null
+++ b/src/cyxtrax/common/mesh_object.py
@@ -0,0 +1,26 @@
+from dataclasses import dataclass
+from pathlib import Path
+import numpy as np
+
+
+@dataclass
+class MeshObject:
+    object_path: Path
+    position_mm: np.ndarray
+    orientation_quat: np.ndarray
+
+    def as_dict(self):
+        return dict(
+            object_path=str(self.object_path),
+            object_position=self.position_mm.astype(np.float64).tolist(),
+            object_orientation=self.orientation_quat.astype(np.float64).tolist(),
+        )
+
+    @classmethod
+    def from_dict(cls: "MeshObject", data_dict):
+        item = cls(
+            Path(data_dict["object_path"]),
+            np.array(data_dict["object_position"]),
+            np.array(data_dict["object_orientation"]),
+        )
+        return item
diff --git a/src/cyxtrax/data/__init__.py b/src/cyxtrax/data/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..8921d24d347c3d8351cd769c4ee42e5c2212550e
--- /dev/null
+++ b/src/cyxtrax/data/__init__.py
@@ -0,0 +1,20 @@
+import importlib.resources
+import numpy as np
+from ..common import MeshObject
+
+
+with importlib.resources.path("cyxtrax.data", "olaf_6.stl") as file_path:
+    olaf_stl = file_path
+    olaf_mesh = MeshObject(
+        olaf_stl,
+        position_mm=np.array([1, 2, 3]),
+        orientation_quat=np.array([0.0, 0.0, 0.0, 1.0]),
+    )
+
+with importlib.resources.path("cyxtrax.data", "scones.stl") as file_path:
+    scones_stl = file_path
+    scones_mesh = MeshObject(
+        scones_stl,
+        position_mm=np.array([0, 0, 0]),
+        orientation_quat=np.array([0.0, 0.0, 0.0, 1.0]),
+    )
diff --git a/CyXTraX/data/cone.aRTist b/src/cyxtrax/data/cone.aRTist
similarity index 100%
rename from CyXTraX/data/cone.aRTist
rename to src/cyxtrax/data/cone.aRTist
diff --git a/CyXTraX/data/cylinder.aRTist b/src/cyxtrax/data/cylinder.aRTist
similarity index 100%
rename from CyXTraX/data/cylinder.aRTist
rename to src/cyxtrax/data/cylinder.aRTist
diff --git a/CyXTraX/data/olaf_6.stl b/src/cyxtrax/data/olaf_6.stl
similarity index 100%
rename from CyXTraX/data/olaf_6.stl
rename to src/cyxtrax/data/olaf_6.stl
diff --git a/CyXTraX/data/scones.stl b/src/cyxtrax/data/scones.stl
similarity index 100%
rename from CyXTraX/data/scones.stl
rename to src/cyxtrax/data/scones.stl
diff --git a/src/cyxtrax/io/__init__.py b/src/cyxtrax/io/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..2fff89e6e43e6ba570c599b610827e48cf68a198
--- /dev/null
+++ b/src/cyxtrax/io/__init__.py
@@ -0,0 +1,8 @@
+from .generate_atlas import record_atlas
+from .load_maps import load_atlas
+
+
+__all__ = [
+    'record_atlas',
+    'load_atlas'
+]
\ No newline at end of file
diff --git a/src/cyxtrax/io/generate_atlas.py b/src/cyxtrax/io/generate_atlas.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b15410b4a49e0228debb122d6224b5343ce7ee8
--- /dev/null
+++ b/src/cyxtrax/io/generate_atlas.py
@@ -0,0 +1,73 @@
+import numpy as np
+import h5py
+from CyXTraX.simulation.artist_bridge import CylindricalProjection
+from CyXTraX.common.mesh_object import MeshObject
+from pathlib import Path
+import json
+
+
+def to_dict(mesh_object=MeshObject) -> dict:
+    return mesh_object.as_dict()
+
+
+def record_atlas(
+    cylindrical_projection: CylindricalProjection,
+    mesh_list: list[MeshObject],
+    atlas_name: str,
+    save_folder: Path,
+    map_bounding_box: tuple[float] = (-50.0, 50.0),
+    number_of_maps: int = 4,
+) -> Path:
+    grid = np.linspace(map_bounding_box[0], map_bounding_box[1], number_of_maps)
+    file_index = len(list(save_folder.glob("*.h5"))) + 1
+    save_path = save_folder / f"{file_index:05}_{atlas_name}.h5"
+    file = h5py.File(save_path, "a")
+    projection = file.require_dataset(
+        "maps",
+        shape=(
+            cylindrical_projection.x_px,
+            cylindrical_projection.y_px,
+            number_of_maps**3,
+        ),  # Initial shape with third dimension as 0
+        maxshape=(
+            cylindrical_projection.x_px,
+            cylindrical_projection.y_px,
+            number_of_maps**3,
+        ),
+        dtype=np.float32,
+    )
+
+    projection_points = file.require_dataset(
+        "positions",
+        shape=(3, number_of_maps**3),  # Initial shape with third dimension as 0
+        maxshape=(3, number_of_maps**3),
+        dtype=np.float32,
+    )
+
+    mesh_list_dict = list(map(to_dict, mesh_list))
+    print(mesh_list_dict)
+
+    file.attrs["mesh_list"] = json.dumps(mesh_list_dict)
+
+    counter = 0
+    for x in grid:
+        for y in grid:
+            for z in grid:
+                # x, y, z = 0, y, 0
+                print(x, y, z)
+                position = np.array([x, y, z])
+
+                image = cylindrical_projection.compute_projection(
+                    position, output_full_ray_projection=True
+                )
+                # current_size = projection.shape[2]
+                # new_size = current_size + 1
+                # projection.resize((cylindrical_projection.x_px, cylindrical_projection.y_px, new_size))
+                projection[:, :, counter : counter + 1] = image[
+                    :, :, np.newaxis
+                ].astype(np.float32)
+
+                # projection_points.resize((3, new_size))
+                projection_points[:, counter : counter + 1] = position.reshape((3, 1))
+                counter += 1
+    return save_path
diff --git a/CyXTraX/io/load_maps.py b/src/cyxtrax/io/load_maps.py
similarity index 56%
rename from CyXTraX/io/load_maps.py
rename to src/cyxtrax/io/load_maps.py
index eb42e5087f452b4f7733e081e2ea1972438b60d1..f0053a9244aeb585c69cbb7af81546a96c3e5f04 100644
--- a/CyXTraX/io/load_maps.py
+++ b/src/cyxtrax/io/load_maps.py
@@ -9,16 +9,13 @@ def from_dict(mesh_dict) -> MeshObject:
     return MeshObject.from_dict(mesh_dict)
 
 
-def load_atlas(load_path: Path
-               ) -> tuple[jnp.ndarray, jnp.ndarray, list[MeshObject]]:
-    
-    with h5py.File(load_path, 'r') as f:
-        maps = jnp.array(f['/maps'][:])
-        points = jnp.array(f['/positions'][:])
-        
-        mesh_object_str = f.attrs['mesh_list']
+def load_atlas(load_path: Path) -> tuple[jnp.ndarray, jnp.ndarray, list[MeshObject]]:
+    with h5py.File(load_path, "r") as f:
+        maps = jnp.array(f["/maps"][:])
+        points = jnp.array(f["/positions"][:])
+
+        mesh_object_str = f.attrs["mesh_list"]
         mesh_object_dict = json.loads(mesh_object_str)
         mesh_object_list = list(map(from_dict, mesh_object_dict))
 
     return maps, points, mesh_object_list
-
diff --git a/src/cyxtrax/mapping/__init__.py b/src/cyxtrax/mapping/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..122cf03b2fe8d11b76711526d46360f17f553186
--- /dev/null
+++ b/src/cyxtrax/mapping/__init__.py
@@ -0,0 +1,6 @@
+from .mapping import map_geometry_2_projection, map_source_2_cylinder
+
+__all__ = [
+    'map_geometry_2_projection',
+    'map_source_2_cylinder'
+]
diff --git a/src/cyxtrax/mapping/mapping.py b/src/cyxtrax/mapping/mapping.py
new file mode 100644
index 0000000000000000000000000000000000000000..e41f5df7fe8a53fa1111bfce07b802c64d74826e
--- /dev/null
+++ b/src/cyxtrax/mapping/mapping.py
@@ -0,0 +1,146 @@
+from jax import numpy as jnp
+import dm_pix as pix
+from jax import jit
+from jax.scipy.spatial.transform import Rotation
+
+
+@jit
+def map_source_2_cylinder(
+    source: jnp.ndarray,
+    maps: jnp.ndarray,
+    map_positions: jnp.ndarray,
+    radius: float = 1000.0,
+    angle_discretisation: int = 2000,
+    pitch: float = jnp.pi,
+) -> tuple[jnp.ndarray, jnp.ndarray]:
+    """
+    source:        1 x 3
+    maps:          u x v x m
+    map_positions:     3 x m
+
+    ---
+
+    cylinder_value:        m x 1
+    """
+
+    # map_positions = map_positions.T # m x 3
+
+    angles = cylindrical_angles(
+        source, map_positions, radius, angle_discretisation, pitch
+    )
+
+    u = jnp.expand_dims(angles[0], 0)  # 1 x m
+    v = jnp.expand_dims(angles[1], 0)  # 1 x m
+    w = jnp.arange(0, maps.shape[2])[jnp.newaxis, ...]  # +0.0001 # 1 x m
+
+    uvw = jnp.concatenate([v, u, w], 0)  # 3 x m
+    values = pix.flat_nd_linear_interpolate(maps, uvw)
+
+    return values, uvw  # m,
+
+
+@jit
+def cylindrical_angles(
+    source: jnp.ndarray,
+    map_positions: jnp.ndarray,
+    radius: float = 1000.0,
+    angle_discretisation: int = 2000,
+    pitch: float = jnp.pi,
+) -> tuple[jnp.ndarray, jnp.ndarray]:
+    source = source.reshape((-1, 1))  # 1 x 3
+    directions = map_positions - source  # m x 3
+    direction_norm_factor = jnp.linalg.norm(directions[:2], axis=0, keepdims=True)
+    directions = directions / direction_norm_factor  # m x 3
+    intersection = directions * radius
+    # sign = jnp.where(intersection[2]>=0, 1, -1)
+    # intersection = intersection * sign
+
+    z_value = intersection[2] / pitch
+    z = z_value + (angle_discretisation) / 2.0
+    beta_value = (
+        (jnp.arctan2(intersection[0], intersection[1]) / jnp.pi)
+        * angle_discretisation
+        / 2
+    )
+    beta = beta_value - ((angle_discretisation - 1.0) / 4.0)
+    angles = jnp.concatenate(
+        (jnp.expand_dims(z, 0) % 2000, jnp.expand_dims(beta, 0) % 2000), axis=0
+    )
+    return angles
+
+
+@jit
+def map_geometry_2_projection(
+    source: jnp.ndarray,
+    detector: jnp.ndarray,
+    detector_orientation: jnp.ndarray,
+    map_positions: jnp.ndarray,
+    projections: jnp.ndarray,
+    pixel_pitch_mm: float = 0.139,
+):
+    """
+    source:               1 x 3
+    detector:             1 x 3
+    detector_orientation: 1 x 4
+    map_positions:            3 x m
+    projections:                  u x v
+    pixel_pitch_mm:               1,
+
+    ---
+
+    projection_value:             m
+    """
+    source = source.reshape((1, 3))
+    detector = detector.reshape((1, 3))
+    detector_orientation = detector_orientation.reshape((1, 4))
+
+    projection_geometry = projection_matrix(
+        source, detector, detector_orientation
+    )  # 3 x 4
+    map_positions_homogen = jnp.ones((1, map_positions.shape[1]))  # 1 x m
+    map_positions_homogen = jnp.concatenate(
+        (map_positions, map_positions_homogen), 0
+    )  # 4 x m
+    uv_px = projection_geometry @ map_positions_homogen  # 3 x m
+    uv_px = uv_px / uv_px[2]
+    uv_px = uv_px / pixel_pitch_mm
+    uv_px = uv_px.at[0, :].multiply(-1)
+    uv_px = uv_px.at[0, :].add((projections.shape[-2]) / 2.0)
+    # uv_px = uv_px.at[0,:].multiply(-1)
+    uv_px = uv_px.at[1, :].add((projections.shape[-2]) / 2.0)
+    uv_px = uv_px[:2]
+
+    uv_px_flip = jnp.flip(uv_px, 0)
+    # uv_px_flip = uv_px
+
+    return pix.flat_nd_linear_interpolate(projections, uv_px_flip), uv_px
+
+
+@jit
+def projection_matrix(
+    source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray
+) -> jnp.ndarray:
+    """
+    source:               1 x 3
+    detector:             1 x 3
+    detector_orientation: 1 x 4
+
+    ---
+
+    projection_matrix =   3 x 4
+    """
+    detector_orientation = detector_orientation / detector_orientation[1, 3]
+    rotation_matrix = Rotation.from_quat(detector_orientation).as_matrix()
+    detector_horizontal_vector = -rotation_matrix[0, :, 0]
+    detector_vertical_vector = -rotation_matrix[0, :, 1]
+    p3x3 = jnp.vstack(
+        [
+            detector_horizontal_vector,
+            detector_vertical_vector,
+            (detector - source).reshape((-1, 3)),
+        ]
+    ).T
+    p3x3_inv = jnp.linalg.inv(p3x3)
+    p4 = p3x3_inv @ (-source).reshape((3, 1))
+    matrix = jnp.concatenate([p3x3_inv, p4], 1)  # 3 x 4
+    return matrix
diff --git a/src/cyxtrax/simulation/__init__.py b/src/cyxtrax/simulation/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ceddce2bc31b45b48999c027cb574f4fba0a2b2c
--- /dev/null
+++ b/src/cyxtrax/simulation/__init__.py
@@ -0,0 +1,8 @@
+from .artist_bridge import CylindricalProjection, load_mesh, SAVEMODES, utility
+
+__all__ = [
+    'CylindricalProjection',
+    'load_mesh',
+    'SAVEMODES',
+    'utility'
+]
\ No newline at end of file
diff --git a/CyXTraX/simulation/artist_bridge.py b/src/cyxtrax/simulation/artist_bridge.py
similarity index 52%
rename from CyXTraX/simulation/artist_bridge.py
rename to src/cyxtrax/simulation/artist_bridge.py
index 0f7ff94bba2f3ac9a4ffcdefe275f2429a1190c9..93d32f2fc703c50a38eaa4e251554effb13c3856 100644
--- a/CyXTraX/simulation/artist_bridge.py
+++ b/src/cyxtrax/simulation/artist_bridge.py
@@ -2,24 +2,27 @@ try:
     from artistlib import API, utility, SAVEMODES  # type: ignore
 except ModuleNotFoundError:
     from warnings import warn
-    warn('The module `artistlib`is not installed. The simulation module is not 100\% usable! \nInstall: https://github.com/wittlsn/aRTist-PythonLib')
-    API = lambda: None
+
+    warn(
+        "The module `artistlib`is not installed. The simulation module is not 100\% usable! \nInstall: https://github.com/wittlsn/aRTist-PythonLib"
+    )
+    def API():
+        return None
     utility = None
     SAVEMODES = None
 from pathlib import Path
 import numpy as np
 import os
-from scipy.spatial.transform import Rotation
 import importlib.resources
 from time import sleep
-from CyXTraX.common.mesh_object import MeshObject
+from cyxtrax.common.mesh_object import MeshObject
 
 # !!!!!!!!!!!!!!!!!!!
 # Read carefully
 #!!!!!!!!!!!!!!!!?!!!
 
 
-# This Script assumes that the detector has a size of 6283.19 mm / 2 pi 
+# This Script assumes that the detector has a size of 6283.19 mm / 2 pi
 # and the curvature is set to the y axis with center on the source.
 
 # The source Position has to be on [0, 0, 0]
@@ -30,6 +33,7 @@ from CyXTraX.common.mesh_object import MeshObject
 
 GLOBAL_COUNTER = 0
 
+
 class CylindricalProjection:
     def __init__(self, api: API = API()) -> None:
         self.api = api
@@ -38,16 +42,16 @@ class CylindricalProjection:
         self.pixel_pitch_mm = 0.139
         self.x_px = 2000
         self.y_px = 2000
-        self.detector_radius_mm = 1000.
+        self.detector_radius_mm = 1000.0
         self.objects = list()
         self._cylindrical = True
 
     @property
-    def cylindrical_mode(self) -> bool: 
+    def cylindrical_mode(self) -> bool:
         return self._cylindrical
 
-    @property 
-    def cone_mode(self) -> bool: 
+    @property
+    def cone_mode(self) -> bool:
         return not self._cylindrical
 
     def translate(self, position: np.ndarray):
@@ -56,31 +60,45 @@ class CylindricalProjection:
         x_s, y_s, z_s = 0, 0, 0
         x_p, y_p, z_p = position[0], position[1], position[2]
 
-        self.api.rc.send(f'::PartList::Invoke {str("S")} SetPosition {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};')
-        self.api.rc.send(f'::PartList::Invoke {str("S")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};')
-
-        self.api.rc.send(f'::PartList::Invoke {str("D")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};')
-        self.api.rc.send(f'::PartList::Invoke {str("D")} SetPosition {str(x_d + x_p)} {str(y_d + y_p)} {str(z_d + z_p)};')
-        self.api.rc.send(f'::XDetector::SetDownCurvedView;')
-
-
-    def compute_projection(self, position: np.ndarray, temp_file_path: Path = Path(r'C:\data'), output_full_ray_projection: bool = True) -> np.ndarray:
+        self.api.rc.send(
+            f'::PartList::Invoke {str("S")} SetPosition {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};'
+        )
+        self.api.rc.send(
+            f'::PartList::Invoke {str("S")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};'
+        )
+
+        self.api.rc.send(
+            f'::PartList::Invoke {str("D")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};'
+        )
+        self.api.rc.send(
+            f'::PartList::Invoke {str("D")} SetPosition {str(x_d + x_p)} {str(y_d + y_p)} {str(z_d + z_p)};'
+        )
+        self.api.rc.send("::XDetector::SetDownCurvedView;")
+
+    def compute_projection(
+        self,
+        position: np.ndarray,
+        temp_file_path: Path = Path(r"C:\data"),
+        output_full_ray_projection: bool = True,
+    ) -> np.ndarray:
         global GLOBAL_COUNTER
         self.translate(position)
-        temp_file = temp_file_path / f'temp_{GLOBAL_COUNTER:01}.tiff'
+        temp_file = temp_file_path / f"temp_{GLOBAL_COUNTER:01}.tiff"
         GLOBAL_COUNTER += 1
         GLOBAL_COUNTER = GLOBAL_COUNTER % 10
 
-        self.api.save_image(temp_file, save_projection_geometry=False, save_mode=SAVEMODES.FLOAT_TIFF)
-        
+        self.api.save_image(
+            temp_file, save_projection_geometry=False, save_mode=SAVEMODES.FLOAT_TIFF
+        )
+
         while not temp_file.exists():
-            print('sleepy sleep sleep ...')
+            print("sleepy sleep sleep ...")
             # The computation of the cylindrical xray tansforms takes time ... aRTist is not programmed for it.
             # This catches problems with the computation and the remote control interfaces
             # It is ugly ... but works ...
             # Also if the mesh is not waterprof the triangle filter of artist seems to have problems.
 
-            sleep(2.)
+            sleep(2.0)
 
         image = utility.load_projection(temp_file, load_projection_geometry=False)[0]
         os.remove(temp_file)
@@ -89,44 +107,57 @@ class CylindricalProjection:
             return self.convert_rays(image)
         else:
             return image
-    
+
     def convert_rays(self, image):
         inter_image = np.roll(image, 1000, 0)
         image += np.flip(inter_image, 1)
-        return image 
-    
+        return image
+
     def set_cylindrical_mode(self):
-        with importlib.resources.path('CyXTraX.data', 'cylinder.aRTist') as file_path:
-            print(f'Load: {file_path}')
+        with importlib.resources.path("cyxtrax.data", "cylinder.aRTist") as file_path:
+            print(f"Load: {file_path}")
             self.api.load_project(file_path)
-            self.x_px = 2000.
-            self.y_px = 2000.
+            self.x_px = 2000.0
+            self.y_px = 2000.0
             self.x_resolution_mm = np.pi
             self.y_resolution_mm = np.pi
-            self.detector_radius_mm = 1000.
+            self.detector_radius_mm = 1000.0
         self._cylindrical = True
-        print('Care! The default pixel pitch etc is set. If changes are made change the state of this class ...')
-    
+        print(
+            "Care! The default pixel pitch etc is set. If changes are made change the state of this class ..."
+        )
+
     def set_cone_mode(self):
-        with importlib.resources.path('CyXTraX.data', 'cone.aRTist') as file_path:
-            print(f'Load: {file_path}')
+        with importlib.resources.path("cyxtrax.data", "cone.aRTist") as file_path:
+            print(f"Load: {file_path}")
             self.api.load_project(file_path)
             self.pixel_pitch_mm = 0.139
         self._cylindrical = False
-        print('Care! The default pixel pitch etc is set. If changes are made change the state of this class ...')
-    
+        print(
+            "Care! The default pixel pitch etc is set. If changes are made change the state of this class ..."
+        )
 
-def load_mesh(cylindrical_projection: CylindricalProjection, object_list: list[MeshObject], cylindrical_mode: bool = True) -> bool:
+
+def load_mesh(
+    cylindrical_projection: CylindricalProjection,
+    object_list: list[MeshObject],
+    cylindrical_mode: bool = True,
+) -> bool:
     if cylindrical_mode:
         cylindrical_projection.set_cylindrical_mode()
     else:
         cylindrical_projection.set_cone_mode()
 
     for mesh_object in object_list:
-        
         object_id = cylindrical_projection.api.load_part(mesh_object.object_path)
-        cylindrical_projection.api.translate(object_id, mesh_object.position_mm[0], mesh_object.position_mm[1], mesh_object.position_mm[2])
-        cylindrical_projection.api.rotate_from_quat(object_id, mesh_object.orientation_quat)
-       
-    return True
+        cylindrical_projection.api.translate(
+            object_id,
+            mesh_object.position_mm[0],
+            mesh_object.position_mm[1],
+            mesh_object.position_mm[2],
+        )
+        cylindrical_projection.api.rotate_from_quat(
+            object_id, mesh_object.orientation_quat
+        )
 
+    return True
diff --git a/src/cyxtrax/simulation/model/__init__.py b/src/cyxtrax/simulation/model/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddd257a4ea7a8a6ad86558ce53971d1a321947ee
--- /dev/null
+++ b/src/cyxtrax/simulation/model/__init__.py
@@ -0,0 +1,10 @@
+from .augemtation_parameters import AugemntationParameter
+from .noise import add_white_noise, add_gaussian_blur
+from .xray import add_material
+
+__all__ = [
+    'AugemntationParameter',
+    'add_white_noise',
+    'add_gaussian_blur',
+    'add_material'
+]
\ No newline at end of file
diff --git a/CyXTraX/simulation/model/augemtation_parameters.py b/src/cyxtrax/simulation/model/augemtation_parameters.py
similarity index 77%
rename from CyXTraX/simulation/model/augemtation_parameters.py
rename to src/cyxtrax/simulation/model/augemtation_parameters.py
index 51f5e1b9857a91141ec0e1a6936ce1f20c944a9b..e478c5b23df199a9ed491e4adaec7cd11410a8ba 100644
--- a/CyXTraX/simulation/model/augemtation_parameters.py
+++ b/src/cyxtrax/simulation/model/augemtation_parameters.py
@@ -1,5 +1,4 @@
 from dataclasses import dataclass
-from jax import random
 
 
 @dataclass
@@ -7,4 +6,4 @@ class AugemntationParameter:
     augmentation_module: str
     augmentation_function: str
     function_parameter: dict
-    input_parameter: dict
\ No newline at end of file
+    input_parameter: dict
diff --git a/CyXTraX/simulation/model/noise.py b/src/cyxtrax/simulation/model/noise.py
similarity index 60%
rename from CyXTraX/simulation/model/noise.py
rename to src/cyxtrax/simulation/model/noise.py
index 76e1a4761714771d60526223527b65a21082c9e6..3ee76dd47feedff75efc596d7314f7005633538a 100644
--- a/CyXTraX/simulation/model/noise.py
+++ b/src/cyxtrax/simulation/model/noise.py
@@ -3,34 +3,37 @@ import dm_pix as pix
 from jax import numpy as jnp, random
 
 
-
-def add_white_noise(maps: jnp.ndarray, mu: jnp.ndarray, sigma: jnp.ndarray, key: random.PRNGKey
-                    ) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]:
+def add_white_noise(
+    maps: jnp.ndarray, mu: jnp.ndarray, sigma: jnp.ndarray, key: random.PRNGKey
+) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]:
     key2use, key4next = random.split(key)
     function_kwargs = dict(key=key2use, shape=maps.shape, dtype=maps.dtype)
     input_kwargs = dict(mu=mu, sigma=sigma)
     maps = maps.at[:].add(random.normal(**function_kwargs) * sigma + mu)
-    
+
     parameters = AugemntationParameter(
-        add_gaussian_blur.__globals__['__name__'],
+        add_gaussian_blur.__globals__["__name__"],
         add_gaussian_blur.__name__,
         function_kwargs,
-        input_kwargs)
-    
+        input_kwargs,
+    )
+
     return maps, parameters, key4next
 
 
-def add_gaussian_blur(maps: jnp.ndarray, sigma: jnp.ndarray, kernel_size: jnp.ndarray, key: random.PRNGKey
-                      ) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]:
+def add_gaussian_blur(
+    maps: jnp.ndarray, sigma: jnp.ndarray, kernel_size: jnp.ndarray, key: random.PRNGKey
+) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]:
     key4next = key
     function_kwargs = dict(sigma=sigma, kernel_size=kernel_size)
     input_kwargs = dict(kernel_size=kernel_size, sigma=sigma)
     maps = pix.gaussian_blur(maps, **function_kwargs)
 
     parameters = AugemntationParameter(
-        add_gaussian_blur.__globals__['__name__'],
+        add_gaussian_blur.__globals__["__name__"],
         add_gaussian_blur.__name__,
         function_kwargs,
-        input_kwargs)
-    
+        input_kwargs,
+    )
+
     return maps, parameters, key4next
diff --git a/src/cyxtrax/simulation/model/pipeline.py b/src/cyxtrax/simulation/model/pipeline.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/CyXTraX/simulation/model/xray.py b/src/cyxtrax/simulation/model/xray.py
similarity index 61%
rename from CyXTraX/simulation/model/xray.py
rename to src/cyxtrax/simulation/model/xray.py
index 978af9c12a760d498022dbf1bb4f7b56635a4f60..57376662543d2994b3491a603f6040e676afd4c1 100644
--- a/CyXTraX/simulation/model/xray.py
+++ b/src/cyxtrax/simulation/model/xray.py
@@ -1,7 +1,6 @@
 from .augemtation_parameters import AugemntationParameter
 
 import xraylib
-import numpy as np
 from jax import numpy as jnp, random
 
 
@@ -10,29 +9,36 @@ def get_attenuation_coefficient_monochrom(element: str, energy_keV: float) -> fl
     return xraylib.CS_Total(element, energy_keV)
 
 
-def get_attenuation_coefficient_polychrom(element: str, energy_keV: float, bins: int) -> float:
+def get_attenuation_coefficient_polychrom(
+    element: str, energy_keV: float, bins: int
+) -> float:
     energies = jnp.linspace(0, energy_keV, bins, endpoint=True)
     for i in range(1, bins):
-        energies = energies.at[i].set(get_attenuation_coefficient_monochrom(element, float(energies[i])))
+        energies = energies.at[i].set(
+            get_attenuation_coefficient_monochrom(element, float(energies[i]))
+        )
     return energies.sum()
 
 
-def add_material(maps: jnp.ndarray, materilal: str, energy_keV: float, bins: int, key: random.PRNGKey):
+def add_material(
+    maps: jnp.ndarray, materilal: str, energy_keV: float, bins: int, key: random.PRNGKey
+):
     key4next = key
     function_kwargs = dict()
     input_kwargs = dict(element=materilal, energy_keV=energy_keV, bins=bins)
     attenuation_coefficient = get_attenuation_coefficient_polychrom(**input_kwargs)
 
     parameters = AugemntationParameter(
-        add_material.__globals__['__name__'],
+        add_material.__globals__["__name__"],
         add_material.__name__,
         function_kwargs,
-        input_kwargs)
+        input_kwargs,
+    )
     maps = maps.at[:].multiply(attenuation_coefficient)
-    
+
     return maps, parameters, key4next
 
 
-if __name__ == '__main__':
-    mu = get_attenuation_coefficient_polychrom('c', 100, 10)
-    print(mu)
\ No newline at end of file
+if __name__ == "__main__":
+    mu = get_attenuation_coefficient_polychrom("c", 100, 10)
+    print(mu)
diff --git a/src/cyxtrax/util/__init__.py b/src/cyxtrax/util/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cyxtrax/util/datasets/__init__.py b/src/cyxtrax/util/datasets/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..8388c33666b5dd9fd516da6dab5af5ce7b9f3d64
--- /dev/null
+++ b/src/cyxtrax/util/datasets/__init__.py
@@ -0,0 +1,9 @@
+from .merge import merge_atlas_and_dict, merge_atlases, merge_lists
+from .pipeline import generate_atlas_from_folder
+
+__all__ = [
+    'merge_atlas_and_dict',
+    'merge_atlases',
+    'merge_lists',
+    'generate_atlas_from_folder'
+]
\ No newline at end of file
diff --git a/CyXTraX/util/datasets/augmentation_pipeline.py b/src/cyxtrax/util/datasets/augmentation_pipeline.py
similarity index 87%
rename from CyXTraX/util/datasets/augmentation_pipeline.py
rename to src/cyxtrax/util/datasets/augmentation_pipeline.py
index 2e82b48a42e8fff91c68c9333e134d5bb4e58094..4e7345dc60679d1ca1f7a520252e1ac57b8acd41 100644
--- a/CyXTraX/util/datasets/augmentation_pipeline.py
+++ b/src/cyxtrax/util/datasets/augmentation_pipeline.py
@@ -1,4 +1,5 @@
-from jax import random, numpy as jnp
+from jax import random
+
 
 class DataAugmentation:
     def __init__(self, key: random.PRNGKey) -> None:
@@ -10,7 +11,6 @@ class DataAugmentation:
         key2save, key2use = random.split(self._key)
         self._key = key2save
         return key2use
-    
+
     def register(self):
         pass
-    
diff --git a/src/cyxtrax/util/datasets/merge.py b/src/cyxtrax/util/datasets/merge.py
new file mode 100644
index 0000000000000000000000000000000000000000..097f39f3356b01219d688a76ea2ca703cfc00b96
--- /dev/null
+++ b/src/cyxtrax/util/datasets/merge.py
@@ -0,0 +1,17 @@
+from jax import numpy as jnp
+
+
+def merge_atlases(carry_atlas: jnp.ndarray, atlas: jnp.ndarray) -> jnp.ndarray:
+    return carry_atlas.at[:].add(atlas) / 2.0
+
+
+def merge_lists(carry_list: list, x: list) -> list:
+    return carry_list.extend(x)
+
+
+def merge_atlas_and_dict(
+    atlas_one, mesh_list_one, atlas_two, mesh_list_two
+) -> tuple[jnp.ndarray, list]:
+    return merge_atlases(atlas_one, atlas_two), merge_lists(
+        mesh_list_one, mesh_list_two
+    )
diff --git a/CyXTraX/util/datasets/pipeline.py b/src/cyxtrax/util/datasets/pipeline.py
similarity index 52%
rename from CyXTraX/util/datasets/pipeline.py
rename to src/cyxtrax/util/datasets/pipeline.py
index cfb4aab76371be841f7dc13c548b8214fa448a2f..fa9f0ef68ec768d5f093136a6b1808f3c0adc027 100644
--- a/CyXTraX/util/datasets/pipeline.py
+++ b/src/cyxtrax/util/datasets/pipeline.py
@@ -7,31 +7,38 @@ from jax.scipy.spatial.transform import Rotation
 
 
 def generate_atlas_from_folder(
-        folder: Path, key: random.PRNGKey,
-        save_folder: Path,
-        map_bounding_box: tuple[float]=(-50., 50.), number_of_maps: int = 4):
+    folder: Path,
+    key: random.PRNGKey,
+    save_folder: Path,
+    map_bounding_box: tuple[float] = (-50.0, 50.0),
+    number_of_maps: int = 4,
+):
     randint_key, postion_key, orientation_key = random.split(key, 3)
-    stl_files = list(folder.glob('*.stl'))
+    stl_files = list(folder.glob("*.stl"))
     number_of_files = len(stl_files)
 
     item_id = random.randint(randint_key, (1,), 0, number_of_files, dtype=jnp.int32)
     random_euler = random.uniform(orientation_key, (3,), minval=-180, maxval=180)
-    rot: Rotation = Rotation.from_euler('xyz', random_euler)
+    rot: Rotation = Rotation.from_euler("xyz", random_euler)
     stl_path: Path = stl_files[item_id[0]]
     mesh_item = MeshObject(
         stl_path,
-        random.truncated_normal(postion_key, -50, 50, (3,)) + random.uniform(postion_key, (3,), minval=-25, maxval=25),
-        rot.as_quat())
+        random.truncated_normal(postion_key, -50, 50, (3,))
+        + random.uniform(postion_key, (3,), minval=-25, maxval=25),
+        rot.as_quat(),
+    )
     mesh_list = [mesh_item]
     cycl_proj = CylindricalProjection()
     load_mesh(cycl_proj, mesh_list)
-    record_atlas(cycl_proj, mesh_list, 
-                 stl_path.stem, save_folder,
-                 map_bounding_box, number_of_maps)
-    
-    
-    
-def merge_atlas_with_data_augmentation(folder: Path,
-                                       data_augmentation_pipeline):
-    
-    pass
\ No newline at end of file
+    record_atlas(
+        cycl_proj,
+        mesh_list,
+        stl_path.stem,
+        save_folder,
+        map_bounding_box,
+        number_of_maps,
+    )
+
+
+def merge_atlas_with_data_augmentation(folder: Path, data_augmentation_pipeline):
+    pass
diff --git a/src/cyxtrax/util/visualisation/__init__.py b/src/cyxtrax/util/visualisation/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..995194029d4ad90bb3a622024fdb845cc1096783
--- /dev/null
+++ b/src/cyxtrax/util/visualisation/__init__.py
@@ -0,0 +1,9 @@
+from .plt import save_map_plot_with_index, voxel_cone_maps, voxel_maps
+from .gif import make_gif
+
+__all__ = [
+    'save_map_plot_with_index',
+    'voxel_cone_maps',
+    'make_gif',
+    'voxel_maps'
+]
\ No newline at end of file
diff --git a/CyXTraX/util/visualisation/gif.py b/src/cyxtrax/util/visualisation/gif.py
similarity index 90%
rename from CyXTraX/util/visualisation/gif.py
rename to src/cyxtrax/util/visualisation/gif.py
index 68e0a043a05348a4c736100c3904db02462cdb2b..77c59c706fd0953ca0bc556f0d3f4e0bd3e2d66b 100644
--- a/CyXTraX/util/visualisation/gif.py
+++ b/src/cyxtrax/util/visualisation/gif.py
@@ -9,7 +9,7 @@ def atlas_gif(load_path: Path):
 
 def load_pil(path: Path) -> Image.Image:
     return Image.open(path)
-    
+
 
 def make_gif(load_path: Path, pattern: str, name: str, duration_ms: float = 100):
     frames = sorted(list(load_path.glob(pattern)))
@@ -17,7 +17,7 @@ def make_gif(load_path: Path, pattern: str, name: str, duration_ms: float = 100)
     frames[0].save(
         load_path / name,
         save_all=True,
-        append_images=frames[1:], 
+        append_images=frames[1:],
         duration=duration_ms,
-        loop=0)
-
+        loop=0,
+    )
diff --git a/CyXTraX/util/visualisation/plt.py b/src/cyxtrax/util/visualisation/plt.py
similarity index 79%
rename from CyXTraX/util/visualisation/plt.py
rename to src/cyxtrax/util/visualisation/plt.py
index 799e528e3702ca60e4d17e5ff24417f698c4b6b2..29704f68e05e151f2855e1ab6c9be46b4f02e1f8 100644
--- a/CyXTraX/util/visualisation/plt.py
+++ b/src/cyxtrax/util/visualisation/plt.py
@@ -135,5 +135,42 @@ def voxel_cone_maps_values(maps: jnp.ndarray, projection: jnp.ndarray,
     if title is not None:
         plt.title(title)
 
+    plt.tight_layout()
+    plt.savefig(save_path)
+
+
+def voxel_maps(maps: jnp.ndarray, save_path: Path, figsize=(24, 10), title: str = None, vmin: bool = False):
+    fig = plt.figure(figsize=figsize)
+
+    ax2 = fig.add_subplot(111)
+    ax2.set_title('Cylindrical Mapping')
+    ax2.axis(False)
+
+    number_of_maps = maps.shape[2]
+    side_length = int(jnp.round(number_of_maps ** (1. / 3.)))
+    counter = 0
+    for z in [0, side_length - 1]:
+        for y in [0, side_length - 1]:
+            for x in [0, side_length - 1]:
+                position = x + y * side_length + z * side_length ** 2
+                if counter >= number_of_maps:
+                    continue
+                ax = fig.add_subplot(3, 3, counter+1)
+                if vmin:
+                    ax.imshow(maps[:, :, position].T, vmin=maps.min(), vmax=maps.max())
+                else:
+                    ax.imshow(maps[:, :, position].T, vmin=maps.min())
+                ax.set_ylabel(r'$z$ / mm')
+                ax.set_xlabel(r'$\alpha$ / rad')
+                ax.set_yticks([0, 1000, 2000]) 
+                ax.set_yticklabels([r'$-3141.5$', r'$0.$',  r'$3141.5$']) 
+                ax.set_xticks([0, 1000, 2000]) 
+                ax.set_xticklabels([r'$-\pi$', r'$0.$',  r'$\pi$']) 
+
+                counter += 1
+                
+    if title is not None:
+        plt.title(title)
+
     plt.tight_layout()
     plt.savefig(save_path)
\ No newline at end of file
diff --git a/temp/scones.png b/temp/scones.png
new file mode 100644
index 0000000000000000000000000000000000000000..b00343ab54e02835bcefa53b8471d7b909fa38ef
Binary files /dev/null and b/temp/scones.png differ
diff --git a/temp/scones_maps.png b/temp/scones_maps.png
new file mode 100644
index 0000000000000000000000000000000000000000..402700766767ee7fc2aaffb36bb0fab823dcb89d
Binary files /dev/null and b/temp/scones_maps.png differ
diff --git a/uv.lock b/uv.lock
new file mode 100644
index 0000000000000000000000000000000000000000..7c477bf8a8b814d9274d5ed12f26652a6292caf6
--- /dev/null
+++ b/uv.lock
@@ -0,0 +1,883 @@
+version = 1
+requires-python = ">=3.10"
+resolution-markers = [
+    "python_full_version < '3.11' and sys_platform == 'linux'",
+    "python_full_version < '3.11' and sys_platform == 'windows'",
+    "python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'windows'",
+    "python_full_version == '3.11.*' and sys_platform == 'linux'",
+    "python_full_version == '3.11.*' and sys_platform == 'windows'",
+    "python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'windows'",
+    "python_full_version == '3.12.*' and sys_platform == 'linux'",
+    "python_full_version == '3.12.*' and sys_platform == 'windows'",
+    "python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'windows'",
+    "python_full_version >= '3.13' and sys_platform == 'linux'",
+    "python_full_version >= '3.13' and sys_platform == 'windows'",
+    "python_full_version >= '3.13' and sys_platform != 'linux' and sys_platform != 'windows'",
+]
+
+[[package]]
+name = "absl-py"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/7a/8f/fc001b92ecc467cc32ab38398bd0bfb45df46e7523bf33c2ad22a505f06e/absl-py-2.1.0.tar.gz", hash = "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff", size = 118055 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/a2/ad/e0d3c824784ff121c03cc031f944bc7e139a8f1870ffd2845cc2dd76f6c4/absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308", size = 133706 },
+]
+
+[[package]]
+name = "artistlib"
+version = "0.1"
+source = { git = "https://github.com/wittlsn/aRTist-PythonLib#14d657783e51f9c94dcafa47bf71a523b85e6d5a" }
+
+[[package]]
+name = "chex"
+version = "0.1.87"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "absl-py" },
+    { name = "jax" },
+    { name = "jaxlib" },
+    { name = "numpy" },
+    { name = "setuptools", marker = "python_full_version >= '3.12'" },
+    { name = "toolz" },
+    { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ba/8a/857474810b64ab135a0c3e594b0453c7f39f140757c4cd26a32bccadcbc4/chex-0.1.87.tar.gz", hash = "sha256:0096d89cc8d898bb521ef4bfbf5c24549022b0e5b301f529ab57238896fe6c5d", size = 90063 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/46/dd/c1ff2eb8fbf95a8ca804abb1cc3ce70b283ee7b4bc653c3abac245670400/chex-0.1.87-py3-none-any.whl", hash = "sha256:ce536475661fd96d21be0c1728ecdbedd03f8ff950c662dfc338c92ea782cb16", size = 99369 },
+]
+
+[[package]]
+name = "contourpy"
+version = "1.3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f5/f6/31a8f28b4a2a4fa0e01085e542f3081ab0588eff8e589d39d775172c9792/contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4", size = 13464370 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/6c/e0/be8dcc796cfdd96708933e0e2da99ba4bb8f9b2caa9d560a50f3f09a65f3/contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7", size = 265366 },
+    { url = "https://files.pythonhosted.org/packages/50/d6/c953b400219443535d412fcbbc42e7a5e823291236bc0bb88936e3cc9317/contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42", size = 249226 },
+    { url = "https://files.pythonhosted.org/packages/6f/b4/6fffdf213ffccc28483c524b9dad46bb78332851133b36ad354b856ddc7c/contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7", size = 308460 },
+    { url = "https://files.pythonhosted.org/packages/cf/6c/118fc917b4050f0afe07179a6dcbe4f3f4ec69b94f36c9e128c4af480fb8/contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab", size = 347623 },
+    { url = "https://files.pythonhosted.org/packages/f9/a4/30ff110a81bfe3abf7b9673284d21ddce8cc1278f6f77393c91199da4c90/contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589", size = 317761 },
+    { url = "https://files.pythonhosted.org/packages/99/e6/d11966962b1aa515f5586d3907ad019f4b812c04e4546cc19ebf62b5178e/contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41", size = 322015 },
+    { url = "https://files.pythonhosted.org/packages/4d/e3/182383743751d22b7b59c3c753277b6aee3637049197624f333dac5b4c80/contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d", size = 1262672 },
+    { url = "https://files.pythonhosted.org/packages/78/53/974400c815b2e605f252c8fb9297e2204347d1755a5374354ee77b1ea259/contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223", size = 1321688 },
+    { url = "https://files.pythonhosted.org/packages/52/29/99f849faed5593b2926a68a31882af98afbeac39c7fdf7de491d9c85ec6a/contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f", size = 171145 },
+    { url = "https://files.pythonhosted.org/packages/a9/97/3f89bba79ff6ff2b07a3cbc40aa693c360d5efa90d66e914f0ff03b95ec7/contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b", size = 216019 },
+    { url = "https://files.pythonhosted.org/packages/b3/1f/9375917786cb39270b0ee6634536c0e22abf225825602688990d8f5c6c19/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad", size = 266356 },
+    { url = "https://files.pythonhosted.org/packages/05/46/9256dd162ea52790c127cb58cfc3b9e3413a6e3478917d1f811d420772ec/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49", size = 250915 },
+    { url = "https://files.pythonhosted.org/packages/e1/5d/3056c167fa4486900dfbd7e26a2fdc2338dc58eee36d490a0ed3ddda5ded/contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66", size = 310443 },
+    { url = "https://files.pythonhosted.org/packages/ca/c2/1a612e475492e07f11c8e267ea5ec1ce0d89971be496c195e27afa97e14a/contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081", size = 348548 },
+    { url = "https://files.pythonhosted.org/packages/45/cf/2c2fc6bb5874158277b4faf136847f0689e1b1a1f640a36d76d52e78907c/contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1", size = 319118 },
+    { url = "https://files.pythonhosted.org/packages/03/33/003065374f38894cdf1040cef474ad0546368eea7e3a51d48b8a423961f8/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d", size = 323162 },
+    { url = "https://files.pythonhosted.org/packages/42/80/e637326e85e4105a802e42959f56cff2cd39a6b5ef68d5d9aee3ea5f0e4c/contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c", size = 1265396 },
+    { url = "https://files.pythonhosted.org/packages/7c/3b/8cbd6416ca1bbc0202b50f9c13b2e0b922b64be888f9d9ee88e6cfabfb51/contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb", size = 1324297 },
+    { url = "https://files.pythonhosted.org/packages/4d/2c/021a7afaa52fe891f25535506cc861c30c3c4e5a1c1ce94215e04b293e72/contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c", size = 171808 },
+    { url = "https://files.pythonhosted.org/packages/8d/2f/804f02ff30a7fae21f98198828d0857439ec4c91a96e20cf2d6c49372966/contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67", size = 217181 },
+    { url = "https://files.pythonhosted.org/packages/c9/92/8e0bbfe6b70c0e2d3d81272b58c98ac69ff1a4329f18c73bd64824d8b12e/contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f", size = 267838 },
+    { url = "https://files.pythonhosted.org/packages/e3/04/33351c5d5108460a8ce6d512307690b023f0cfcad5899499f5c83b9d63b1/contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6", size = 251549 },
+    { url = "https://files.pythonhosted.org/packages/51/3d/aa0fe6ae67e3ef9f178389e4caaaa68daf2f9024092aa3c6032e3d174670/contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639", size = 303177 },
+    { url = "https://files.pythonhosted.org/packages/56/c3/c85a7e3e0cab635575d3b657f9535443a6f5d20fac1a1911eaa4bbe1aceb/contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c", size = 341735 },
+    { url = "https://files.pythonhosted.org/packages/dd/8d/20f7a211a7be966a53f474bc90b1a8202e9844b3f1ef85f3ae45a77151ee/contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06", size = 314679 },
+    { url = "https://files.pythonhosted.org/packages/6e/be/524e377567defac0e21a46e2a529652d165fed130a0d8a863219303cee18/contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09", size = 320549 },
+    { url = "https://files.pythonhosted.org/packages/0f/96/fdb2552a172942d888915f3a6663812e9bc3d359d53dafd4289a0fb462f0/contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd", size = 1263068 },
+    { url = "https://files.pythonhosted.org/packages/2a/25/632eab595e3140adfa92f1322bf8915f68c932bac468e89eae9974cf1c00/contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35", size = 1322833 },
+    { url = "https://files.pythonhosted.org/packages/73/e3/69738782e315a1d26d29d71a550dbbe3eb6c653b028b150f70c1a5f4f229/contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb", size = 172681 },
+    { url = "https://files.pythonhosted.org/packages/0c/89/9830ba00d88e43d15e53d64931e66b8792b46eb25e2050a88fec4a0df3d5/contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b", size = 218283 },
+    { url = "https://files.pythonhosted.org/packages/53/a1/d20415febfb2267af2d7f06338e82171824d08614084714fb2c1dac9901f/contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3", size = 267879 },
+    { url = "https://files.pythonhosted.org/packages/aa/45/5a28a3570ff6218d8bdfc291a272a20d2648104815f01f0177d103d985e1/contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7", size = 251573 },
+    { url = "https://files.pythonhosted.org/packages/39/1c/d3f51540108e3affa84f095c8b04f0aa833bb797bc8baa218a952a98117d/contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84", size = 303184 },
+    { url = "https://files.pythonhosted.org/packages/00/56/1348a44fb6c3a558c1a3a0cd23d329d604c99d81bf5a4b58c6b71aab328f/contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0", size = 340262 },
+    { url = "https://files.pythonhosted.org/packages/2b/23/00d665ba67e1bb666152131da07e0f24c95c3632d7722caa97fb61470eca/contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b", size = 313806 },
+    { url = "https://files.pythonhosted.org/packages/5a/42/3cf40f7040bb8362aea19af9a5fb7b32ce420f645dd1590edcee2c657cd5/contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da", size = 319710 },
+    { url = "https://files.pythonhosted.org/packages/05/32/f3bfa3fc083b25e1a7ae09197f897476ee68e7386e10404bdf9aac7391f0/contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14", size = 1264107 },
+    { url = "https://files.pythonhosted.org/packages/1c/1e/1019d34473a736664f2439542b890b2dc4c6245f5c0d8cdfc0ccc2cab80c/contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8", size = 1322458 },
+    { url = "https://files.pythonhosted.org/packages/22/85/4f8bfd83972cf8909a4d36d16b177f7b8bdd942178ea4bf877d4a380a91c/contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294", size = 172643 },
+    { url = "https://files.pythonhosted.org/packages/cc/4a/fb3c83c1baba64ba90443626c228ca14f19a87c51975d3b1de308dd2cf08/contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087", size = 218301 },
+    { url = "https://files.pythonhosted.org/packages/76/65/702f4064f397821fea0cb493f7d3bc95a5d703e20954dce7d6d39bacf378/contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8", size = 278972 },
+    { url = "https://files.pythonhosted.org/packages/80/85/21f5bba56dba75c10a45ec00ad3b8190dbac7fd9a8a8c46c6116c933e9cf/contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b", size = 263375 },
+    { url = "https://files.pythonhosted.org/packages/0a/64/084c86ab71d43149f91ab3a4054ccf18565f0a8af36abfa92b1467813ed6/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973", size = 307188 },
+    { url = "https://files.pythonhosted.org/packages/3d/ff/d61a4c288dc42da0084b8d9dc2aa219a850767165d7d9a9c364ff530b509/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18", size = 345644 },
+    { url = "https://files.pythonhosted.org/packages/ca/aa/00d2313d35ec03f188e8f0786c2fc61f589306e02fdc158233697546fd58/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8", size = 317141 },
+    { url = "https://files.pythonhosted.org/packages/8d/6a/b5242c8cb32d87f6abf4f5e3044ca397cb1a76712e3fa2424772e3ff495f/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6", size = 323469 },
+    { url = "https://files.pythonhosted.org/packages/6f/a6/73e929d43028a9079aca4bde107494864d54f0d72d9db508a51ff0878593/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2", size = 1260894 },
+    { url = "https://files.pythonhosted.org/packages/2b/1e/1e726ba66eddf21c940821df8cf1a7d15cb165f0682d62161eaa5e93dae1/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927", size = 1314829 },
+    { url = "https://files.pythonhosted.org/packages/d1/09/60e486dc2b64c94ed33e58dcfb6f808192c03dfc5574c016218b9b7680dc/contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c", size = 261886 },
+    { url = "https://files.pythonhosted.org/packages/19/20/b57f9f7174fcd439a7789fb47d764974ab646fa34d1790551de386457a8e/contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779", size = 311008 },
+    { url = "https://files.pythonhosted.org/packages/74/fc/5040d42623a1845d4f17a418e590fd7a79ae8cb2bad2b2f83de63c3bdca4/contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4", size = 215690 },
+]
+
+[[package]]
+name = "cycler"
+version = "0.12.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 },
+]
+
+[[package]]
+name = "cyxtrax"
+version = "0.1.0"
+source = { editable = "." }
+dependencies = [
+    { name = "artistlib" },
+    { name = "dm-pix" },
+    { name = "h5py" },
+    { name = "jax", marker = "sys_platform == 'linux' or sys_platform == 'windows'" },
+    { name = "jax", extra = ["cuda12"], marker = "sys_platform == 'linux'" },
+    { name = "matplotlib" },
+    { name = "numpy" },
+    { name = "ruff" },
+    { name = "scipy" },
+    { name = "xraylib" },
+]
+
+[package.metadata]
+requires-dist = [
+    { name = "artistlib", git = "https://github.com/wittlsn/aRTist-PythonLib" },
+    { name = "dm-pix", specifier = ">=0.4.3" },
+    { name = "h5py", specifier = ">=3.12.1" },
+    { name = "jax", marker = "sys_platform == 'windows'", specifier = ">=0.4.35" },
+    { name = "jax", extras = ["cuda12"], marker = "sys_platform == 'linux'", specifier = ">=0.4.35" },
+    { name = "matplotlib", specifier = ">=3.9.2" },
+    { name = "numpy", specifier = ">=2.1.3" },
+    { name = "ruff", specifier = ">=0.7.3" },
+    { name = "scipy", specifier = ">=1.14.1" },
+    { name = "xraylib", specifier = ">=4.1.5" },
+]
+
+[[package]]
+name = "dm-pix"
+version = "0.4.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "chex" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a7/c3/04acc8314dedc0eb59809d3da8b0a1cdf07c72f150463f81db7b0f4694a4/dm_pix-0.4.3.tar.gz", hash = "sha256:03031112c73b1877e2eaee42d7f066a70feb7538df17c4edc7025e5174725a1a", size = 48187 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/a5/56/a4a1bee7dc5b0f8da5d34489e160ce1cad4cceaa24435434fa9724974fe6/dm_pix-0.4.3-py3-none-any.whl", hash = "sha256:462ed274dbd071400ed7ea6ff3242bf71433691fcc38d483fe6a849366c44647", size = 56492 },
+]
+
+[[package]]
+name = "fonttools"
+version = "4.54.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/11/1d/70b58e342e129f9c0ce030029fb4b2b0670084bbbfe1121d008f6a1e361c/fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285", size = 3463867 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/db/f9/285c9a2d0e86b9bf2babfe19bec00502361fda56cea144d6a269ab9a32e6/fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2", size = 2766970 },
+    { url = "https://files.pythonhosted.org/packages/2f/9a/9d899e7ae55b0dd30632e6ca36c0f5fa1205b1b096ec171c9be903673058/fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882", size = 2254639 },
+    { url = "https://files.pythonhosted.org/packages/16/6f/b99e0c347732fb003077a2cff38c26f381969b74329aa5597e344d540fe1/fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10", size = 4574346 },
+    { url = "https://files.pythonhosted.org/packages/e5/12/9a45294a7c4520cc32936edd15df1d5c24af701d2f5f51070a9a43d7664b/fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e", size = 4630045 },
+    { url = "https://files.pythonhosted.org/packages/64/52/ba4f00eb6003e4089264cd9ce126cddec2b39c78f1ab01be9dc389a197ca/fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e", size = 4569527 },
+    { url = "https://files.pythonhosted.org/packages/41/ff/85f93a14c8acf978f332508f980dcaff5ed5f0cf284371eb101a78f0b1f4/fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44", size = 4741677 },
+    { url = "https://files.pythonhosted.org/packages/6f/f0/06ea7d9f8b7b6d4758a50271517db04039c4c6da8fa0475d417e005624d0/fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02", size = 2166797 },
+    { url = "https://files.pythonhosted.org/packages/71/73/545c817e34b8c34585291951722e1a5ae579380deb009576d9d244b13ab0/fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d", size = 2210552 },
+    { url = "https://files.pythonhosted.org/packages/aa/2c/8b5d82fe2d9c7f260fb73121418f5e07d4e38c329ea3886a5b0e55586113/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20", size = 2768112 },
+    { url = "https://files.pythonhosted.org/packages/37/2e/f94118b92f7b6a9ec93840101b64bfdd09f295b266133857e8e852a5c35c/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2", size = 2254739 },
+    { url = "https://files.pythonhosted.org/packages/45/4b/8a32f56a13e78256192f77d6b65583c43538c7955f5420887bb574b91ddf/fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7", size = 4879772 },
+    { url = "https://files.pythonhosted.org/packages/96/13/748b7f7239893ff0796de11074b0ad8aa4c3da2d9f4d79a128b0b16147f3/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07", size = 4927686 },
+    { url = "https://files.pythonhosted.org/packages/7c/82/91bc5a378b4a0593fa90ea706f68ce7e9e871c6873e0d91e134d107758db/fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8", size = 4890789 },
+    { url = "https://files.pythonhosted.org/packages/ea/ca/82be5d4f8b78405cdb3f7f3f1316af5e8db93216121f19da9f684a35beee/fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a", size = 5061351 },
+    { url = "https://files.pythonhosted.org/packages/da/2f/fd6e1b01c80c473c3ac52492dcf8d26cdf5f4a89b4f30875ecfbda55e7ff/fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc", size = 2166210 },
+    { url = "https://files.pythonhosted.org/packages/63/f1/3a081cd047d83b5966cb0d7ef3fea929ee6eddeb94d8fbfdb2a19bd60cc7/fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6", size = 2211946 },
+    { url = "https://files.pythonhosted.org/packages/27/b6/f9d365932dcefefdcc794985f8846471e60932070c557e0f66ed195fccec/fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d", size = 2761873 },
+    { url = "https://files.pythonhosted.org/packages/67/9d/cfbfe36e5061a8f68b154454ba2304eb01f40d4ba9b63e41d9058909baed/fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08", size = 2251828 },
+    { url = "https://files.pythonhosted.org/packages/90/41/5573e074739efd9227dd23647724f01f6f07ad062fe09d02e91c5549dcf7/fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263", size = 4792544 },
+    { url = "https://files.pythonhosted.org/packages/08/07/aa85cc62abcc940b25d14b542cf585eebf4830032a7f6a1395d696bb3231/fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab", size = 4875892 },
+    { url = "https://files.pythonhosted.org/packages/47/23/c5726c2615446c498a976bed21c35a242a97eee39930a2655d616ca885cc/fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d", size = 4769822 },
+    { url = "https://files.pythonhosted.org/packages/8f/7b/87f7f7d35e0732ac67422dfa6f05e2b568fb6ca2dcd7f3e4f500293cfd75/fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714", size = 5029455 },
+    { url = "https://files.pythonhosted.org/packages/e0/09/241aa498587889576838aa73c78d22b70ce06970807a5475d372baa7ccb7/fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac", size = 2154411 },
+    { url = "https://files.pythonhosted.org/packages/b9/0a/a57caaff3bc880779317cb157e5b49dc47fad54effe027016abd355b0651/fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e", size = 2200412 },
+    { url = "https://files.pythonhosted.org/packages/05/3d/cc515cae84a11d696f2cb7c139a90997b15f02e2e97ec09a5d79302cbcd7/fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff", size = 2749174 },
+    { url = "https://files.pythonhosted.org/packages/03/03/05d4b22d1a674d066380657f60bbc0eda2d206446912e676d1a33a206878/fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb", size = 2246267 },
+    { url = "https://files.pythonhosted.org/packages/52/c3/bb6086adb675e8b0963a7dbb7769e7118c95b687dd318cd660aefd4b4c8c/fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a", size = 4855090 },
+    { url = "https://files.pythonhosted.org/packages/80/a1/d7192b6a104e3f9ea8e5b1c3463a6240399f0fa826a782eff636cbe0495a/fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c", size = 5005449 },
+    { url = "https://files.pythonhosted.org/packages/5a/6c/ecfd5c6cd8c9006e85b128d073af26bb263e8aa47506374cb14b25bcf65f/fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58", size = 2152496 },
+    { url = "https://files.pythonhosted.org/packages/63/da/f7a1d837de419e3d4cccbd0dbf53c7399f610f65ceb9bcbf2480f3ae7950/fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d", size = 2197257 },
+    { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 },
+]
+
+[[package]]
+name = "h5py"
+version = "3.12.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cc/0c/5c2b0a88158682aeafb10c1c2b735df5bc31f165bfe192f2ee9f2a23b5f1/h5py-3.12.1.tar.gz", hash = "sha256:326d70b53d31baa61f00b8aa5f95c2fcb9621a3ee8365d770c551a13dbbcbfdf", size = 411457 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/df/7d/b21045fbb004ad8bb6fb3be4e6ca903841722706f7130b9bba31ef2f88e3/h5py-3.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f0f1a382cbf494679c07b4371f90c70391dedb027d517ac94fa2c05299dacda", size = 3402133 },
+    { url = "https://files.pythonhosted.org/packages/29/a7/3c2a33fba1da64a0846744726fd067a92fb8abb887875a0dd8e3bac8b45d/h5py-3.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb65f619dfbdd15e662423e8d257780f9a66677eae5b4b3fc9dca70b5fd2d2a3", size = 2866436 },
+    { url = "https://files.pythonhosted.org/packages/1e/d0/4bf67c3937a2437c20844165766ddd1a1817ae6b9544c3743050d8e0f403/h5py-3.12.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b15d8dbd912c97541312c0e07438864d27dbca857c5ad634de68110c6beb1c2", size = 5168596 },
+    { url = "https://files.pythonhosted.org/packages/85/bc/e76f4b2096e0859225f5441d1b7f5e2041fffa19fc2c16756c67078417aa/h5py-3.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59685fe40d8c1fbbee088c88cd4da415a2f8bee5c270337dc5a1c4aa634e3307", size = 5341537 },
+    { url = "https://files.pythonhosted.org/packages/99/bd/fb8ed45308bb97e04c02bd7aed324ba11e6a4bf9ed73967ca2a168e9cf92/h5py-3.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:577d618d6b6dea3da07d13cc903ef9634cde5596b13e832476dd861aaf651f3e", size = 2990575 },
+    { url = "https://files.pythonhosted.org/packages/33/61/c463dc5fc02fbe019566d067a9d18746cd3c664f29c9b8b3c3f9ed025365/h5py-3.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ccd9006d92232727d23f784795191bfd02294a4f2ba68708825cb1da39511a93", size = 3410828 },
+    { url = "https://files.pythonhosted.org/packages/95/9d/eb91a9076aa998bb2179d6b1788055ea09cdf9d6619cd967f1d3321ed056/h5py-3.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ad8a76557880aed5234cfe7279805f4ab5ce16b17954606cca90d578d3e713ef", size = 2872586 },
+    { url = "https://files.pythonhosted.org/packages/b0/62/e2b1f9723ff713e3bd3c16dfeceec7017eadc21ef063d8b7080c0fcdc58a/h5py-3.12.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1473348139b885393125126258ae2d70753ef7e9cec8e7848434f385ae72069e", size = 5273038 },
+    { url = "https://files.pythonhosted.org/packages/e1/89/118c3255d6ff2db33b062ec996a762d99ae50c21f54a8a6047ae8eda1b9f/h5py-3.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:018a4597f35092ae3fb28ee851fdc756d2b88c96336b8480e124ce1ac6fb9166", size = 5452688 },
+    { url = "https://files.pythonhosted.org/packages/1d/4d/cbd3014eb78d1e449b29beba1f3293a841aa8086c6f7968c383c2c7ff076/h5py-3.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fdf95092d60e8130ba6ae0ef7a9bd4ade8edbe3569c13ebbaf39baefffc5ba4", size = 3006095 },
+    { url = "https://files.pythonhosted.org/packages/d4/e1/ea9bfe18a3075cdc873f0588ff26ce394726047653557876d7101bf0c74e/h5py-3.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06a903a4e4e9e3ebbc8b548959c3c2552ca2d70dac14fcfa650d9261c66939ed", size = 3372538 },
+    { url = "https://files.pythonhosted.org/packages/0d/74/1009b663387c025e8fa5f3ee3cf3cd0d99b1ad5c72eeb70e75366b1ce878/h5py-3.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b3b8f3b48717e46c6a790e3128d39c61ab595ae0a7237f06dfad6a3b51d5351", size = 2868104 },
+    { url = "https://files.pythonhosted.org/packages/af/52/c604adc06280c15a29037d4aa79a24fe54d8d0b51085e81ed24b2fa995f7/h5py-3.12.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:050a4f2c9126054515169c49cb900949814987f0c7ae74c341b0c9f9b5056834", size = 5194606 },
+    { url = "https://files.pythonhosted.org/packages/fa/63/eeaacff417b393491beebabb8a3dc5342950409eb6d7b39d437289abdbae/h5py-3.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c4b41d1019322a5afc5082864dfd6359f8935ecd37c11ac0029be78c5d112c9", size = 5413256 },
+    { url = "https://files.pythonhosted.org/packages/86/f7/bb465dcb92ca3521a15cbe1031f6d18234dbf1fb52a6796a00bfaa846ebf/h5py-3.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4d51919110a030913201422fb07987db4338eba5ec8c5a15d6fab8e03d443fc", size = 2993055 },
+    { url = "https://files.pythonhosted.org/packages/23/1c/ecdd0efab52c24f2a9bf2324289828b860e8dd1e3c5ada3cf0889e14fdc1/h5py-3.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:513171e90ed92236fc2ca363ce7a2fc6f2827375efcbb0cc7fbdd7fe11fecafc", size = 3346239 },
+    { url = "https://files.pythonhosted.org/packages/93/cd/5b6f574bf3e318bbe305bc93ba45181676550eb44ba35e006d2e98004eaa/h5py-3.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59400f88343b79655a242068a9c900001a34b63e3afb040bd7cdf717e440f653", size = 2843416 },
+    { url = "https://files.pythonhosted.org/packages/8a/4f/b74332f313bfbe94ba03fff784219b9db385e6139708e55b11490149f90a/h5py-3.12.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e465aee0ec353949f0f46bf6c6f9790a2006af896cee7c178a8c3e5090aa32", size = 5154390 },
+    { url = "https://files.pythonhosted.org/packages/1a/57/93ea9e10a6457ea8d3b867207deb29a527e966a08a84c57ffd954e32152a/h5py-3.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba51c0c5e029bb5420a343586ff79d56e7455d496d18a30309616fdbeed1068f", size = 5378244 },
+    { url = "https://files.pythonhosted.org/packages/50/51/0bbf3663062b2eeee78aa51da71e065f8a0a6e3cb950cc7020b4444999e6/h5py-3.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:52ab036c6c97055b85b2a242cb540ff9590bacfda0c03dd0cf0661b311f522f8", size = 2979760 },
+]
+
+[[package]]
+name = "jax"
+version = "0.4.35"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "jaxlib" },
+    { name = "ml-dtypes" },
+    { name = "numpy" },
+    { name = "opt-einsum" },
+    { name = "scipy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/e3/34/21da583b9596e72bb8e95b6197dee0a44b96b9ea2c147fccabd43ca5515b/jax-0.4.35.tar.gz", hash = "sha256:c0c986993026b10bf6f607fecb7417377460254640766ce40f1fef3fd139c12e", size = 1861189 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/62/20/6c57c50c0ccc645fea1895950f1e5cd02f961ee44b3ffe83617fa46b0c1d/jax-0.4.35-py3-none-any.whl", hash = "sha256:fa99e909a31424abfec750019a6dd36f6acc18a6e7d40e2c0086b932cc351325", size = 2158621 },
+]
+
+[package.optional-dependencies]
+cuda12 = [
+    { name = "jax-cuda12-plugin", extra = ["with-cuda"], marker = "sys_platform == 'linux'" },
+    { name = "jaxlib", marker = "sys_platform == 'linux'" },
+]
+
+[[package]]
+name = "jax-cuda12-pjrt"
+version = "0.4.35"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/8f/ba/12d0f831331e0eb7dafc49eb1bd0a905098aca917456d6ccf57efd57b908/jax_cuda12_pjrt-0.4.35-py3-none-manylinux2014_aarch64.whl", hash = "sha256:81980f1696749351364d7999ee5cb21bedd9d14daa01b40eb60d20f2210da11c", size = 84301075 },
+    { url = "https://files.pythonhosted.org/packages/d7/aa/f15ea857ad9bcff7a0c942dc570ca718b026cc0cc5c513525bb08cacf3c0/jax_cuda12_pjrt-0.4.35-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0ffe7e1ba65659bd5738c2cc5addaf0a56205d2188eec5da194b63c068e1fdd2", size = 100760554 },
+]
+
+[[package]]
+name = "jax-cuda12-plugin"
+version = "0.4.35"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "jax-cuda12-pjrt", marker = "sys_platform == 'linux'" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/d7/eb/f317f426b8ea56a9e634d6eb06230d9d2d01cc34066defeb7d3fd6ab5708/jax_cuda12_plugin-0.4.35-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:30290570a8a0547e59c1fd927aefb693d4a4fe15aae23c0a1e5c34eed82bef49", size = 15545891 },
+    { url = "https://files.pythonhosted.org/packages/f5/2b/c39f961139b655d3d8ea203615486eab5aceea47540a50f377ff98958f43/jax_cuda12_plugin-0.4.35-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:5fcc47ef49cb8ff5ceaa67d143a18b22c78456a0967d243963312901d978e96e", size = 15519460 },
+    { url = "https://files.pythonhosted.org/packages/7e/58/8f7eba5d6199e7b99903f85bbd97c456523f4f910717c409e5d082289723/jax_cuda12_plugin-0.4.35-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:982c9b6fcc6f7a64cb4cb19aa2f9f98cfc29faac28ef04721b4617da76d81949", size = 15546115 },
+    { url = "https://files.pythonhosted.org/packages/5a/45/d1f9595ee26c2457f71df5b4a786775d77a8d2e96a9697445fd777bab35a/jax_cuda12_plugin-0.4.35-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:1752de1060f4671be6da47b88c1e0bcb1d2fe9e99958e95aa375a9b17dfa1656", size = 15520457 },
+    { url = "https://files.pythonhosted.org/packages/0f/6b/2b08b0a33dbbd410ed6746d2f12c67b4b7a1318590cf05fa3ca7dbff4c46/jax_cuda12_plugin-0.4.35-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:767e53cd0ab0f543f7ac64c74e326b4e7145ca6424d0e7128373e5777012e6d9", size = 15541645 },
+    { url = "https://files.pythonhosted.org/packages/23/a1/781f98da41b9abf63a1468c5babbafa7b1bdb766c081386644a4034fbdef/jax_cuda12_plugin-0.4.35-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:80aa5e628e8e9dd4f89b767f73900152033c3bf6d5f49dc2081e93f9bac1c9dc", size = 15516745 },
+    { url = "https://files.pythonhosted.org/packages/17/5d/4cb713a31a92e451739732a86b2dd18ed7ca89825c347c47717d89843108/jax_cuda12_plugin-0.4.35-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:c241bd2decf9eeaad6c35aeccf5ede56447dc4152fc82d9272d103cb51450abe", size = 15542531 },
+    { url = "https://files.pythonhosted.org/packages/d2/d1/7517b43aa06dcfa39bb9ef9ee485c2a612c2aa822f113871b36d84340d52/jax_cuda12_plugin-0.4.35-cp313-cp313-manylinux2014_x86_64.whl", hash = "sha256:91326529c11f64c954f1421cdf60d2bdfaa51caf2152dc743a20557933bae8d9", size = 15516650 },
+]
+
+[package.optional-dependencies]
+with-cuda = [
+    { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cuda-cupti-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cuda-nvcc-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cuda-runtime-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cudnn-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cufft-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cusolver-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-nccl-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" },
+]
+
+[[package]]
+name = "jaxlib"
+version = "0.4.34"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "ml-dtypes" },
+    { name = "numpy" },
+    { name = "scipy" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/24/31/2e254fe2fc23201775a7d0ccd1bcde892cfa349eb805744b81b15e0dcf74/jaxlib-0.4.34-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:b7a212a3cb5c6acc201c32ae4f4b5f5a9ac09457fbb77ba8db5ce7e7d4adc214", size = 87399257 },
+    { url = "https://files.pythonhosted.org/packages/1e/67/6a344c357caad33e84b871925cd043b4218fc13a427266d1a1dedcb1c095/jaxlib-0.4.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:45d719a2ce0ebf21255a277b71d756f3609b7b5be70cddc5d88fd58c35219de0", size = 67617952 },
+    { url = "https://files.pythonhosted.org/packages/dd/ea/12c836126419ca80248228f2236831617eedb1e3640c34c942606f33bb08/jaxlib-0.4.34-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:3e60bc826933082e99b19b87c21818a8d26fcdb01f418d47cedff554746fd6cc", size = 69391770 },
+    { url = "https://files.pythonhosted.org/packages/e4/b0/a5bd34643c070e50829beec217189eab1acdfea334df1f9ddb4e5f8bec0f/jaxlib-0.4.34-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:d840e64b85f8865404d6d225b9bb340e158df1457152a361b05680e24792b232", size = 86094116 },
+    { url = "https://files.pythonhosted.org/packages/d8/c9/35a4233fe74ddd5aabe89aac1b3992b0e463982564252d21fd263d4d9992/jaxlib-0.4.34-cp310-cp310-win_amd64.whl", hash = "sha256:b0001c8f0e2b1c7bc99e4f314b524a340d25653505c1a1484d4041a9d3617f6f", size = 55206389 },
+    { url = "https://files.pythonhosted.org/packages/bf/14/00a3385532d72ab51bd8e9f8c3e19a2e257667955565e9fc10236771dd06/jaxlib-0.4.34-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8ee3f93836e53c86556ccd9449a4ea43516ee05184d031a71dd692e81259f7d9", size = 87420889 },
+    { url = "https://files.pythonhosted.org/packages/66/78/d1535ee73fe505dc6c8831c19c4846afdce7df5acefb9f8ee885aa73d700/jaxlib-0.4.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c9d3adcae43a33aad4332be9c2aedc5ef751d1e755f917a5afb30c7872eacaa8", size = 67635880 },
+    { url = "https://files.pythonhosted.org/packages/aa/06/3e09e794acf308e170905d732eca0d041449503c47505cc22e8ef78a989d/jaxlib-0.4.34-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:571ef03259835458111596a71a2f4a6fabf4ec34595df4cea555035362ac5bf0", size = 69421901 },
+    { url = "https://files.pythonhosted.org/packages/c7/d0/6bc81c0b1d507f403e6085ce76a429e6d7f94749d742199252e299dd1424/jaxlib-0.4.34-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:3bcfa639ca3cfaf86c8ceebd5fc0d47300fd98a078014a1d0cc03133e1523d5f", size = 86114491 },
+    { url = "https://files.pythonhosted.org/packages/9d/5d/7e71019af5f6fdebe6c10eab97d01f44b931d94609330da9e142cb155f8c/jaxlib-0.4.34-cp311-cp311-win_amd64.whl", hash = "sha256:133070d4fec5525ffea4dc72956398c1cf647a04dcb37f8a935ee82af78d9965", size = 55241262 },
+    { url = "https://files.pythonhosted.org/packages/bc/42/5038983664494dfb50f8669a662d965d7ea62f9250e40d8cd36dcf9ac3dd/jaxlib-0.4.34-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:c7b3e724a30426a856070aba0192b5d199e95b4411070e7ad96ad8b196877b10", size = 87473956 },
+    { url = "https://files.pythonhosted.org/packages/87/2e/8a75d3107c019c370c50c01acc205da33f9d6fba830950401a772a8e9f6d/jaxlib-0.4.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:096f0ca309d41fa692a9d1f2f9baab1c5c8ca0749876ebb3f748e738a27c7ff4", size = 67650276 },
+    { url = "https://files.pythonhosted.org/packages/af/09/cceae2d251a506b4297679d10ee9f5e905a6b992b0687d553c9470ffd1db/jaxlib-0.4.34-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:1a30771d85fa77f9ab8f18e63240f455ab3a3f87660ed7b8d5eea6ceecbe5c1e", size = 69431284 },
+    { url = "https://files.pythonhosted.org/packages/e7/0d/4faf839e3c8ce2a5b615df64427be3e870899c72c0ebfb5859348150aba1/jaxlib-0.4.34-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:48272e9034ff868d4328cf0055a07882fd2be93f59dfb6283af7de491f9d1290", size = 86151183 },
+    { url = "https://files.pythonhosted.org/packages/a4/bc/a38f99071fca6cc31ae949e508a23b0de5de559da594443bb625a1adb8f3/jaxlib-0.4.34-cp312-cp312-win_amd64.whl", hash = "sha256:901cb4040ed24eae40071d8114ea8d10dff436277fa74a1a5b9e7206f641151c", size = 55278745 },
+    { url = "https://files.pythonhosted.org/packages/21/4e/fab0606683af7aa9284a32d2b188ff132cffb0ee3ea04d941a547eb776d1/jaxlib-0.4.34-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:72e22e99a5dc890a64443c3fc12f13f20091f578c405a76de077ba42b4c62cd7", size = 87474367 },
+    { url = "https://files.pythonhosted.org/packages/3e/1b/709be16d543a3db5b471ee5e7d089c57484c386b08499923e43bd8da5d0b/jaxlib-0.4.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c303f5acaf6c56ce5ff133a923c9b6247bdebedde15bd2c893c24be4d8f71306", size = 67651281 },
+    { url = "https://files.pythonhosted.org/packages/85/9e/f3801096cd4a2c764af7a1f6b683c769706602ea72b27ec35bacfcc4cd4f/jaxlib-0.4.34-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:7be673a876ebd1aef440fb7e3ebaf99a91abeb550c9728c644b7d7c7b5d7c108", size = 69432987 },
+    { url = "https://files.pythonhosted.org/packages/e6/79/61301f55b24c3a898ef9bc4e13600b66e3f838623fc6f87648ac1ccbca01/jaxlib-0.4.34-cp313-cp313-manylinux2014_x86_64.whl", hash = "sha256:87f25a477cd279840e53718403f97092eba0e8a945fcab47bcf435b6f9119dda", size = 86152550 },
+    { url = "https://files.pythonhosted.org/packages/16/b0/e682d02126e0062b58dec0f0851048592396f74c24b4a4412dce4ddbbadb/jaxlib-0.4.34-cp313-cp313-win_amd64.whl", hash = "sha256:6b43a974c5d91a19912d138f2658dd8dbb7d30dcdff5c961d896c673e872b611", size = 55279410 },
+]
+
+[[package]]
+name = "kiwisolver"
+version = "1.4.7"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60", size = 97286 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/97/14/fc943dd65268a96347472b4fbe5dcc2f6f55034516f80576cd0dd3a8930f/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6", size = 122440 },
+    { url = "https://files.pythonhosted.org/packages/1e/46/e68fed66236b69dd02fcdb506218c05ac0e39745d696d22709498896875d/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17", size = 65758 },
+    { url = "https://files.pythonhosted.org/packages/ef/fa/65de49c85838681fc9cb05de2a68067a683717321e01ddafb5b8024286f0/kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9", size = 64311 },
+    { url = "https://files.pythonhosted.org/packages/42/9c/cc8d90f6ef550f65443bad5872ffa68f3dee36de4974768628bea7c14979/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9", size = 1637109 },
+    { url = "https://files.pythonhosted.org/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c", size = 1617814 },
+    { url = "https://files.pythonhosted.org/packages/12/5d/c36140313f2510e20207708adf36ae4919416d697ee0236b0ddfb6fd1050/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599", size = 1400881 },
+    { url = "https://files.pythonhosted.org/packages/56/d0/786e524f9ed648324a466ca8df86298780ef2b29c25313d9a4f16992d3cf/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05", size = 1512972 },
+    { url = "https://files.pythonhosted.org/packages/67/5a/77851f2f201e6141d63c10a0708e996a1363efaf9e1609ad0441b343763b/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407", size = 1444787 },
+    { url = "https://files.pythonhosted.org/packages/06/5f/1f5eaab84355885e224a6fc8d73089e8713dc7e91c121f00b9a1c58a2195/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278", size = 2199212 },
+    { url = "https://files.pythonhosted.org/packages/b5/28/9152a3bfe976a0ae21d445415defc9d1cd8614b2910b7614b30b27a47270/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5", size = 2346399 },
+    { url = "https://files.pythonhosted.org/packages/26/f6/453d1904c52ac3b400f4d5e240ac5fec25263716723e44be65f4d7149d13/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad", size = 2308688 },
+    { url = "https://files.pythonhosted.org/packages/5a/9a/d4968499441b9ae187e81745e3277a8b4d7c60840a52dc9d535a7909fac3/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895", size = 2445493 },
+    { url = "https://files.pythonhosted.org/packages/07/c9/032267192e7828520dacb64dfdb1d74f292765f179e467c1cba97687f17d/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3", size = 2262191 },
+    { url = "https://files.pythonhosted.org/packages/6c/ad/db0aedb638a58b2951da46ddaeecf204be8b4f5454df020d850c7fa8dca8/kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc", size = 46644 },
+    { url = "https://files.pythonhosted.org/packages/12/ca/d0f7b7ffbb0be1e7c2258b53554efec1fd652921f10d7d85045aff93ab61/kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c", size = 55877 },
+    { url = "https://files.pythonhosted.org/packages/97/6c/cfcc128672f47a3e3c0d918ecb67830600078b025bfc32d858f2e2d5c6a4/kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a", size = 48347 },
+    { url = "https://files.pythonhosted.org/packages/e9/44/77429fa0a58f941d6e1c58da9efe08597d2e86bf2b2cce6626834f49d07b/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54", size = 122442 },
+    { url = "https://files.pythonhosted.org/packages/e5/20/8c75caed8f2462d63c7fd65e16c832b8f76cda331ac9e615e914ee80bac9/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95", size = 65762 },
+    { url = "https://files.pythonhosted.org/packages/f4/98/fe010f15dc7230f45bc4cf367b012d651367fd203caaa992fd1f5963560e/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935", size = 64319 },
+    { url = "https://files.pythonhosted.org/packages/8b/1b/b5d618f4e58c0675654c1e5051bcf42c776703edb21c02b8c74135541f60/kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb", size = 1334260 },
+    { url = "https://files.pythonhosted.org/packages/b8/01/946852b13057a162a8c32c4c8d2e9ed79f0bb5d86569a40c0b5fb103e373/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02", size = 1426589 },
+    { url = "https://files.pythonhosted.org/packages/70/d1/c9f96df26b459e15cf8a965304e6e6f4eb291e0f7a9460b4ad97b047561e/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51", size = 1541080 },
+    { url = "https://files.pythonhosted.org/packages/d3/73/2686990eb8b02d05f3de759d6a23a4ee7d491e659007dd4c075fede4b5d0/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052", size = 1470049 },
+    { url = "https://files.pythonhosted.org/packages/a7/4b/2db7af3ed3af7c35f388d5f53c28e155cd402a55432d800c543dc6deb731/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18", size = 1426376 },
+    { url = "https://files.pythonhosted.org/packages/05/83/2857317d04ea46dc5d115f0df7e676997bbd968ced8e2bd6f7f19cfc8d7f/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545", size = 2222231 },
+    { url = "https://files.pythonhosted.org/packages/0d/b5/866f86f5897cd4ab6d25d22e403404766a123f138bd6a02ecb2cdde52c18/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b", size = 2368634 },
+    { url = "https://files.pythonhosted.org/packages/c1/ee/73de8385403faba55f782a41260210528fe3273d0cddcf6d51648202d6d0/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36", size = 2329024 },
+    { url = "https://files.pythonhosted.org/packages/a1/e7/cd101d8cd2cdfaa42dc06c433df17c8303d31129c9fdd16c0ea37672af91/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3", size = 2468484 },
+    { url = "https://files.pythonhosted.org/packages/e1/72/84f09d45a10bc57a40bb58b81b99d8f22b58b2040c912b7eb97ebf625bf2/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523", size = 2284078 },
+    { url = "https://files.pythonhosted.org/packages/d2/d4/71828f32b956612dc36efd7be1788980cb1e66bfb3706e6dec9acad9b4f9/kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d", size = 46645 },
+    { url = "https://files.pythonhosted.org/packages/a1/65/d43e9a20aabcf2e798ad1aff6c143ae3a42cf506754bcb6a7ed8259c8425/kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b", size = 56022 },
+    { url = "https://files.pythonhosted.org/packages/35/b3/9f75a2e06f1b4ca00b2b192bc2b739334127d27f1d0625627ff8479302ba/kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376", size = 48536 },
+    { url = "https://files.pythonhosted.org/packages/97/9c/0a11c714cf8b6ef91001c8212c4ef207f772dd84540104952c45c1f0a249/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2", size = 121808 },
+    { url = "https://files.pythonhosted.org/packages/f2/d8/0fe8c5f5d35878ddd135f44f2af0e4e1d379e1c7b0716f97cdcb88d4fd27/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a", size = 65531 },
+    { url = "https://files.pythonhosted.org/packages/80/c5/57fa58276dfdfa612241d640a64ca2f76adc6ffcebdbd135b4ef60095098/kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee", size = 63894 },
+    { url = "https://files.pythonhosted.org/packages/8b/e9/26d3edd4c4ad1c5b891d8747a4f81b1b0aba9fb9721de6600a4adc09773b/kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640", size = 1369296 },
+    { url = "https://files.pythonhosted.org/packages/b6/67/3f4850b5e6cffb75ec40577ddf54f7b82b15269cc5097ff2e968ee32ea7d/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f", size = 1461450 },
+    { url = "https://files.pythonhosted.org/packages/52/be/86cbb9c9a315e98a8dc6b1d23c43cffd91d97d49318854f9c37b0e41cd68/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483", size = 1579168 },
+    { url = "https://files.pythonhosted.org/packages/0f/00/65061acf64bd5fd34c1f4ae53f20b43b0a017a541f242a60b135b9d1e301/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258", size = 1507308 },
+    { url = "https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e", size = 1464186 },
+    { url = "https://files.pythonhosted.org/packages/0a/0f/529d0a9fffb4d514f2782c829b0b4b371f7f441d61aa55f1de1c614c4ef3/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107", size = 2247877 },
+    { url = "https://files.pythonhosted.org/packages/d1/e1/66603ad779258843036d45adcbe1af0d1a889a07af4635f8b4ec7dccda35/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948", size = 2404204 },
+    { url = "https://files.pythonhosted.org/packages/8d/61/de5fb1ca7ad1f9ab7970e340a5b833d735df24689047de6ae71ab9d8d0e7/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038", size = 2352461 },
+    { url = "https://files.pythonhosted.org/packages/ba/d2/0edc00a852e369827f7e05fd008275f550353f1f9bcd55db9363d779fc63/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383", size = 2501358 },
+    { url = "https://files.pythonhosted.org/packages/84/15/adc15a483506aec6986c01fb7f237c3aec4d9ed4ac10b756e98a76835933/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520", size = 2314119 },
+    { url = "https://files.pythonhosted.org/packages/36/08/3a5bb2c53c89660863a5aa1ee236912269f2af8762af04a2e11df851d7b2/kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b", size = 46367 },
+    { url = "https://files.pythonhosted.org/packages/19/93/c05f0a6d825c643779fc3c70876bff1ac221f0e31e6f701f0e9578690d70/kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb", size = 55884 },
+    { url = "https://files.pythonhosted.org/packages/d2/f9/3828d8f21b6de4279f0667fb50a9f5215e6fe57d5ec0d61905914f5b6099/kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a", size = 48528 },
+    { url = "https://files.pythonhosted.org/packages/c4/06/7da99b04259b0f18b557a4effd1b9c901a747f7fdd84cf834ccf520cb0b2/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e", size = 121913 },
+    { url = "https://files.pythonhosted.org/packages/97/f5/b8a370d1aa593c17882af0a6f6755aaecd643640c0ed72dcfd2eafc388b9/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6", size = 65627 },
+    { url = "https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750", size = 63888 },
+    { url = "https://files.pythonhosted.org/packages/bf/3e/0b7172793d0f41cae5c923492da89a2ffcd1adf764c16159ca047463ebd3/kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d", size = 1369145 },
+    { url = "https://files.pythonhosted.org/packages/77/92/47d050d6f6aced2d634258123f2688fbfef8ded3c5baf2c79d94d91f1f58/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379", size = 1461448 },
+    { url = "https://files.pythonhosted.org/packages/9c/1b/8f80b18e20b3b294546a1adb41701e79ae21915f4175f311a90d042301cf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c", size = 1578750 },
+    { url = "https://files.pythonhosted.org/packages/a4/fe/fe8e72f3be0a844f257cadd72689c0848c6d5c51bc1d60429e2d14ad776e/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34", size = 1507175 },
+    { url = "https://files.pythonhosted.org/packages/39/fa/cdc0b6105d90eadc3bee525fecc9179e2b41e1ce0293caaf49cb631a6aaf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1", size = 1463963 },
+    { url = "https://files.pythonhosted.org/packages/6e/5c/0c03c4e542720c6177d4f408e56d1c8315899db72d46261a4e15b8b33a41/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f", size = 2248220 },
+    { url = "https://files.pythonhosted.org/packages/3d/ee/55ef86d5a574f4e767df7da3a3a7ff4954c996e12d4fbe9c408170cd7dcc/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b", size = 2404463 },
+    { url = "https://files.pythonhosted.org/packages/0f/6d/73ad36170b4bff4825dc588acf4f3e6319cb97cd1fb3eb04d9faa6b6f212/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27", size = 2352842 },
+    { url = "https://files.pythonhosted.org/packages/0b/16/fa531ff9199d3b6473bb4d0f47416cdb08d556c03b8bc1cccf04e756b56d/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a", size = 2501635 },
+    { url = "https://files.pythonhosted.org/packages/78/7e/aa9422e78419db0cbe75fb86d8e72b433818f2e62e2e394992d23d23a583/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee", size = 2314556 },
+    { url = "https://files.pythonhosted.org/packages/a8/b2/15f7f556df0a6e5b3772a1e076a9d9f6c538ce5f05bd590eca8106508e06/kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07", size = 46364 },
+    { url = "https://files.pythonhosted.org/packages/0b/db/32e897e43a330eee8e4770bfd2737a9584b23e33587a0812b8e20aac38f7/kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76", size = 55887 },
+    { url = "https://files.pythonhosted.org/packages/c8/a4/df2bdca5270ca85fd25253049eb6708d4127be2ed0e5c2650217450b59e9/kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650", size = 48530 },
+    { url = "https://files.pythonhosted.org/packages/ac/59/741b79775d67ab67ced9bb38552da688c0305c16e7ee24bba7a2be253fb7/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643", size = 59491 },
+    { url = "https://files.pythonhosted.org/packages/58/cc/fb239294c29a5656e99e3527f7369b174dd9cc7c3ef2dea7cb3c54a8737b/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706", size = 57648 },
+    { url = "https://files.pythonhosted.org/packages/3b/ef/2f009ac1f7aab9f81efb2d837301d255279d618d27b6015780115ac64bdd/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6", size = 84257 },
+    { url = "https://files.pythonhosted.org/packages/81/e1/c64f50987f85b68b1c52b464bb5bf73e71570c0f7782d626d1eb283ad620/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2", size = 80906 },
+    { url = "https://files.pythonhosted.org/packages/fd/71/1687c5c0a0be2cee39a5c9c389e546f9c6e215e46b691d00d9f646892083/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4", size = 79951 },
+    { url = "https://files.pythonhosted.org/packages/ea/8b/d7497df4a1cae9367adf21665dd1f896c2a7aeb8769ad77b662c5e2bcce7/kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a", size = 55715 },
+]
+
+[[package]]
+name = "matplotlib"
+version = "3.9.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "contourpy" },
+    { name = "cycler" },
+    { name = "fonttools" },
+    { name = "kiwisolver" },
+    { name = "numpy" },
+    { name = "packaging" },
+    { name = "pillow" },
+    { name = "pyparsing" },
+    { name = "python-dateutil" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9e/d8/3d7f706c69e024d4287c1110d74f7dabac91d9843b99eadc90de9efc8869/matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92", size = 36088381 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/6a/9d/84eeb82ecdd3ba71b12dd6ab5c820c5cc1e868003ecb3717d41b589ec02a/matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb", size = 7893310 },
+    { url = "https://files.pythonhosted.org/packages/36/98/cbacbd30241369d099f9c13a2b6bc3b7068d85214f5b5795e583ac3d8aba/matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4", size = 7764089 },
+    { url = "https://files.pythonhosted.org/packages/a8/a0/917f3c6d3a8774a3a1502d9f3dfc1456e07c1fa0c211a23b75a69e154180/matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64", size = 8192377 },
+    { url = "https://files.pythonhosted.org/packages/8d/9d/d06860390f9d154fa884f1740a5456378fb153ff57443c91a4a32bab7092/matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66", size = 8303983 },
+    { url = "https://files.pythonhosted.org/packages/9e/a7/c0e848ed7de0766c605af62d8097472a37f1a81d93e9afe94faa5890f24d/matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a", size = 9083318 },
+    { url = "https://files.pythonhosted.org/packages/09/6c/0fa50c001340a45cde44853c116d6551aea741e59a7261c38f473b53553b/matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae", size = 7819628 },
+    { url = "https://files.pythonhosted.org/packages/77/c2/f9d7fe80a8fcce9bb128d1381c6fe41a8d286d7e18395e273002e8e0fa34/matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772", size = 7902925 },
+    { url = "https://files.pythonhosted.org/packages/28/ba/8be09886eb56ac04a218a1dc3fa728a5c4cac60b019b4f1687885166da00/matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41", size = 7773193 },
+    { url = "https://files.pythonhosted.org/packages/e6/9a/5991972a560db3ab621312a7ca5efec339ae2122f25901c0846865c4b72f/matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f", size = 8202378 },
+    { url = "https://files.pythonhosted.org/packages/01/75/6c7ce560e95714a10fcbb3367d1304975a1a3e620f72af28921b796403f3/matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447", size = 8314361 },
+    { url = "https://files.pythonhosted.org/packages/6e/49/dc7384c6c092958e0b75e754efbd9e52500154939c3d715789cee9fb8a53/matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e", size = 9091428 },
+    { url = "https://files.pythonhosted.org/packages/8b/ce/15b0bb2fb29b3d46211d8ca740b96b5232499fc49200b58b8d571292c9a6/matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7", size = 7829377 },
+    { url = "https://files.pythonhosted.org/packages/82/de/54f7f38ce6de79cb77d513bb3eaa4e0b1031e9fd6022214f47943fa53a88/matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9", size = 7892511 },
+    { url = "https://files.pythonhosted.org/packages/35/3e/5713b84a02b24b2a4bd4d6673bfc03017e6654e1d8793ece783b7ed4d484/matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d", size = 7769370 },
+    { url = "https://files.pythonhosted.org/packages/5b/bd/c404502aa1824456d2862dd6b9b0c1917761a51a32f7f83ff8cf94b6d117/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7", size = 8193260 },
+    { url = "https://files.pythonhosted.org/packages/27/75/de5b9cd67648051cae40039da0c8cbc497a0d99acb1a1f3d087cd66d27b7/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c", size = 8306310 },
+    { url = "https://files.pythonhosted.org/packages/de/e3/2976e4e54d7ee76eaf54b7639fdc10a223d05c2bdded7045233e9871e469/matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e", size = 9086717 },
+    { url = "https://files.pythonhosted.org/packages/d2/92/c2b9464a0562feb6ae780bdc152364810862e07ef5e6affa2b7686028db2/matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3", size = 7832805 },
+    { url = "https://files.pythonhosted.org/packages/5c/7f/8932eac316b32f464b8f9069f151294dcd892c8fbde61fe8bcd7ba7f7f7e/matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9", size = 7893012 },
+    { url = "https://files.pythonhosted.org/packages/90/89/9db9db3dd0ff3e2c49e452236dfe29e60b5586a88f8928ca1d153d0da8b5/matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa", size = 7769810 },
+    { url = "https://files.pythonhosted.org/packages/67/26/d2661cdc2e1410b8929c5f12dfd521e4528abfed1b3c3d5a28ac48258b43/matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b", size = 8193779 },
+    { url = "https://files.pythonhosted.org/packages/95/70/4839eaa672bf4eacc98ebc8d23633e02b6daf39e294e7433c4ab11a689be/matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413", size = 8306260 },
+    { url = "https://files.pythonhosted.org/packages/88/62/7b263b2cb2724b45d3a4f9c8c6137696cc3ef037d44383fb01ac2a9555c2/matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b", size = 9086073 },
+    { url = "https://files.pythonhosted.org/packages/b0/6d/3572fe243c74112fef120f0bc86f5edd21f49b60e8322fc7f6a01fe945dd/matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49", size = 7833041 },
+    { url = "https://files.pythonhosted.org/packages/03/8f/9d505be3eb2f40ec731674fb6b47d10cc3147bbd6a9ea7a08c8da55415c6/matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03", size = 7933657 },
+    { url = "https://files.pythonhosted.org/packages/5d/68/44b458b9794bcff2a66921f8c9a8110a50a0bb099bd5f7cabb428a1dc765/matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30", size = 7799276 },
+    { url = "https://files.pythonhosted.org/packages/47/79/8486d4ddcaaf676314b5fb58e8fe19d1a6210a443a7c31fa72d4215fcb87/matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51", size = 8221027 },
+    { url = "https://files.pythonhosted.org/packages/56/62/72a472181578c3d035dcda0d0fa2e259ba2c4cb91132588a348bb705b70d/matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c", size = 8329097 },
+    { url = "https://files.pythonhosted.org/packages/01/8a/760f7fce66b39f447ad160800619d0bd5d0936d2b4633587116534a4afe0/matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e", size = 9093770 },
+]
+
+[[package]]
+name = "ml-dtypes"
+version = "0.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ab/79/717c5e22ad25d63ce3acdfe8ff8d64bdedec18914256c59b838218708b16/ml_dtypes-0.5.0.tar.gz", hash = "sha256:3e7d3a380fe73a63c884f06136f8baa7a5249cc8e9fdec677997dd78549f8128", size = 699367 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/83/50/0a2048895a764b138638b5e7a62436545eb206948a5e6f77d9d5a4b02479/ml_dtypes-0.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c32138975797e681eb175996d64356bcfa124bdbb6a70460b9768c2b35a6fa4", size = 736793 },
+    { url = "https://files.pythonhosted.org/packages/0b/b1/95e7995f031bb3890884ddb22e331f24c49b0a4a8f6c448ff5984c86012e/ml_dtypes-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab046f2ff789b1f11b2491909682c5d089934835f9a760fafc180e47dcb676b8", size = 4387416 },
+    { url = "https://files.pythonhosted.org/packages/9a/5b/d47361f882ff2ae27d764f314d18706c69859da60a6c78e6c9e81714c792/ml_dtypes-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7a9152f5876fef565516aa5dd1dccd6fc298a5891b2467973905103eb5c7856", size = 4496271 },
+    { url = "https://files.pythonhosted.org/packages/e6/0c/a89f5c0fe9e48ed6e7e27d53e045711ee3d5b850bece5ee22fb0fb24b281/ml_dtypes-0.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:968fede07d1f9b926a63df97d25ac656cac1a57ebd33701734eaf704bc55d8d8", size = 211915 },
+    { url = "https://files.pythonhosted.org/packages/fe/29/8968fd7ee026c0d04c553fb1ce1cd67f9da668cd567d62c0cdc995ce989e/ml_dtypes-0.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60275f2b51b56834e840c4809fca840565f9bf8e9a73f6d8c94f5b5935701215", size = 736792 },
+    { url = "https://files.pythonhosted.org/packages/19/93/14896596644dad2e041ac5ca7237e6233c484f7defa186ff88b18ee6110b/ml_dtypes-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76942f6aeb5c40766d5ea62386daa4148e6a54322aaf5b53eae9e7553240222f", size = 4392038 },
+    { url = "https://files.pythonhosted.org/packages/89/65/ffdbf3489b0ba2213674ea347fad3a11747be64d2d23d888f9e5abe80a18/ml_dtypes-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e7534392682c3098bc7341648c650864207169c654aed83143d7a19c67ae06f", size = 4499448 },
+    { url = "https://files.pythonhosted.org/packages/bf/31/058b9bcf9a81abd51623985add78711a915e4b0f6045baa5f9a0b41eb039/ml_dtypes-0.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:dc74fd9995513d33eac63d64e436240f5494ec74d522a9f0920194942fc3d2d7", size = 211916 },
+    { url = "https://files.pythonhosted.org/packages/1c/b7/a067839f6e435785f34b09d96938dccb3a5d9502037de243cb84a2eb3f23/ml_dtypes-0.5.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d4b1a70a3e5219790d6b55b9507606fc4e02911d1497d16c18dd721eb7efe7d0", size = 750226 },
+    { url = "https://files.pythonhosted.org/packages/31/75/bf571247bb3dbea73aa33ccae57ce322b9688003cfee2f68d303ab7b987b/ml_dtypes-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a988bac6572630e1e9c2edd9b1277b4eefd1c86209e52b0d061b775ac33902ff", size = 4420139 },
+    { url = "https://files.pythonhosted.org/packages/6f/d3/1321715a95e856d4ef4fba24e4351cf5e4c89d459ad132a8cba5fe257d72/ml_dtypes-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a38df8df61194aeaae1ab7579075779b4ad32cd1cffd012c28be227fa7f2a70a", size = 4471130 },
+    { url = "https://files.pythonhosted.org/packages/00/3a/40c40b78a7eb456837817bfa2c5bc442db59aefdf21c5ecb94700037813d/ml_dtypes-0.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:afa08343069874a30812871d639f9c02b4158ace065601406a493a8511180c02", size = 213187 },
+    { url = "https://files.pythonhosted.org/packages/b3/4a/18f670a2703e771a6775fbc354208e597ff062a88efb0cecc220a282210b/ml_dtypes-0.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d3b3db9990c3840986a0e70524e122cfa32b91139c3653df76121ba7776e015f", size = 753345 },
+    { url = "https://files.pythonhosted.org/packages/ed/c6/358d85e274e22d53def0c85f3cbe0933475fa3cf6922e9dca66eb25cb22f/ml_dtypes-0.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e04fde367b2fe901b1d47234426fe8819909bd1dd862a5adb630f27789c20599", size = 4424962 },
+    { url = "https://files.pythonhosted.org/packages/4c/b4/d766586e24e7a073333c8eb8bd9275f3c6fe0569b509ae7b1699d4f00c74/ml_dtypes-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54415257f00eb44fbcc807454efac3356f75644f1cbfc2d4e5522a72ae1dacab", size = 4475201 },
+    { url = "https://files.pythonhosted.org/packages/14/87/30323ad2e52f56262019a4493fe5f5e71067c5561ce7e2f9c75de520f5e8/ml_dtypes-0.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:cb5cc7b25acabd384f75bbd78892d0c724943f3e2e1986254665a1aa10982e07", size = 213195 },
+]
+
+[[package]]
+name = "numpy"
+version = "2.1.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/25/ca/1166b75c21abd1da445b97bf1fa2f14f423c6cfb4fc7c4ef31dccf9f6a94/numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", size = 20166090 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/f1/80/d572a4737626372915bca41c3afbfec9d173561a39a0a61bacbbfd1dafd4/numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", size = 21152472 },
+    { url = "https://files.pythonhosted.org/packages/6f/bb/7bfba10c791ae3bb6716da77ad85a82d5fac07fc96fb0023ef0571df9d20/numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", size = 13747967 },
+    { url = "https://files.pythonhosted.org/packages/da/d6/2df7bde35f0478455f0be5934877b3e5a505f587b00230f54a519a6b55a5/numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", size = 5354921 },
+    { url = "https://files.pythonhosted.org/packages/d1/bb/75b945874f931494891eac6ca06a1764d0e8208791f3addadb2963b83527/numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", size = 6888603 },
+    { url = "https://files.pythonhosted.org/packages/68/a7/fde73636f6498dbfa6d82fc336164635fe592f1ad0d13285fcb6267fdc1c/numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", size = 13889862 },
+    { url = "https://files.pythonhosted.org/packages/05/db/5d9c91b2e1e2e72be1369278f696356d44975befcae830daf2e667dcb54f/numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", size = 16328151 },
+    { url = "https://files.pythonhosted.org/packages/3e/6a/7eb732109b53ae64a29e25d7e68eb9d6611037f6354875497008a49e74d3/numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", size = 16704107 },
+    { url = "https://files.pythonhosted.org/packages/88/cc/278113b66a1141053cbda6f80e4200c6da06b3079c2d27bda1fde41f2c1f/numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4", size = 14385789 },
+    { url = "https://files.pythonhosted.org/packages/f5/69/eb20f5e1bfa07449bc67574d2f0f7c1e6b335fb41672e43861a7727d85f2/numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", size = 6536706 },
+    { url = "https://files.pythonhosted.org/packages/8e/8b/1c131ab5a94c1086c289c6e1da1d843de9dbd95fe5f5ee6e61904c9518e2/numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", size = 12864165 },
+    { url = "https://files.pythonhosted.org/packages/ad/81/c8167192eba5247593cd9d305ac236847c2912ff39e11402e72ae28a4985/numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", size = 21156252 },
+    { url = "https://files.pythonhosted.org/packages/da/74/5a60003fc3d8a718d830b08b654d0eea2d2db0806bab8f3c2aca7e18e010/numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", size = 13784119 },
+    { url = "https://files.pythonhosted.org/packages/47/7c/864cb966b96fce5e63fcf25e1e4d957fe5725a635e5f11fe03f39dd9d6b5/numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", size = 5352978 },
+    { url = "https://files.pythonhosted.org/packages/09/ac/61d07930a4993dd9691a6432de16d93bbe6aa4b1c12a5e573d468eefc1ca/numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", size = 6892570 },
+    { url = "https://files.pythonhosted.org/packages/27/2f/21b94664f23af2bb52030653697c685022119e0dc93d6097c3cb45bce5f9/numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", size = 13896715 },
+    { url = "https://files.pythonhosted.org/packages/7a/f0/80811e836484262b236c684a75dfc4ba0424bc670e765afaa911468d9f39/numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", size = 16339644 },
+    { url = "https://files.pythonhosted.org/packages/fa/81/ce213159a1ed8eb7d88a2a6ef4fbdb9e4ffd0c76b866c350eb4e3c37e640/numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", size = 16712217 },
+    { url = "https://files.pythonhosted.org/packages/7d/84/4de0b87d5a72f45556b2a8ee9fc8801e8518ec867fc68260c1f5dcb3903f/numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", size = 14399053 },
+    { url = "https://files.pythonhosted.org/packages/7e/1c/e5fabb9ad849f9d798b44458fd12a318d27592d4bc1448e269dec070ff04/numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", size = 6534741 },
+    { url = "https://files.pythonhosted.org/packages/1e/48/a9a4b538e28f854bfb62e1dea3c8fea12e90216a276c7777ae5345ff29a7/numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", size = 12869487 },
+    { url = "https://files.pythonhosted.org/packages/8a/f0/385eb9970309643cbca4fc6eebc8bb16e560de129c91258dfaa18498da8b/numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", size = 20849658 },
+    { url = "https://files.pythonhosted.org/packages/54/4a/765b4607f0fecbb239638d610d04ec0a0ded9b4951c56dc68cef79026abf/numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", size = 13492258 },
+    { url = "https://files.pythonhosted.org/packages/bd/a7/2332679479c70b68dccbf4a8eb9c9b5ee383164b161bee9284ac141fbd33/numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", size = 5090249 },
+    { url = "https://files.pythonhosted.org/packages/c1/67/4aa00316b3b981a822c7a239d3a8135be2a6945d1fd11d0efb25d361711a/numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", size = 6621704 },
+    { url = "https://files.pythonhosted.org/packages/5e/da/1a429ae58b3b6c364eeec93bf044c532f2ff7b48a52e41050896cf15d5b1/numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", size = 13606089 },
+    { url = "https://files.pythonhosted.org/packages/9e/3e/3757f304c704f2f0294a6b8340fcf2be244038be07da4cccf390fa678a9f/numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", size = 16043185 },
+    { url = "https://files.pythonhosted.org/packages/43/97/75329c28fea3113d00c8d2daf9bc5828d58d78ed661d8e05e234f86f0f6d/numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", size = 16410751 },
+    { url = "https://files.pythonhosted.org/packages/ad/7a/442965e98b34e0ae9da319f075b387bcb9a1e0658276cc63adb8c9686f7b/numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", size = 14082705 },
+    { url = "https://files.pythonhosted.org/packages/ac/b6/26108cf2cfa5c7e03fb969b595c93131eab4a399762b51ce9ebec2332e80/numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", size = 6239077 },
+    { url = "https://files.pythonhosted.org/packages/a6/84/fa11dad3404b7634aaab50733581ce11e5350383311ea7a7010f464c0170/numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", size = 12566858 },
+    { url = "https://files.pythonhosted.org/packages/4d/0b/620591441457e25f3404c8057eb924d04f161244cb8a3680d529419aa86e/numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f", size = 20836263 },
+    { url = "https://files.pythonhosted.org/packages/45/e1/210b2d8b31ce9119145433e6ea78046e30771de3fe353f313b2778142f34/numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598", size = 13507771 },
+    { url = "https://files.pythonhosted.org/packages/55/44/aa9ee3caee02fa5a45f2c3b95cafe59c44e4b278fbbf895a93e88b308555/numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57", size = 5075805 },
+    { url = "https://files.pythonhosted.org/packages/78/d6/61de6e7e31915ba4d87bbe1ae859e83e6582ea14c6add07c8f7eefd8488f/numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe", size = 6608380 },
+    { url = "https://files.pythonhosted.org/packages/3e/46/48bdf9b7241e317e6cf94276fe11ba673c06d1fdf115d8b4ebf616affd1a/numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43", size = 13602451 },
+    { url = "https://files.pythonhosted.org/packages/70/50/73f9a5aa0810cdccda9c1d20be3cbe4a4d6ea6bfd6931464a44c95eef731/numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56", size = 16039822 },
+    { url = "https://files.pythonhosted.org/packages/ad/cd/098bc1d5a5bc5307cfc65ee9369d0ca658ed88fbd7307b0d49fab6ca5fa5/numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a", size = 16411822 },
+    { url = "https://files.pythonhosted.org/packages/83/a2/7d4467a2a6d984549053b37945620209e702cf96a8bc658bc04bba13c9e2/numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef", size = 14079598 },
+    { url = "https://files.pythonhosted.org/packages/e9/6a/d64514dcecb2ee70bfdfad10c42b76cab657e7ee31944ff7a600f141d9e9/numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f", size = 6236021 },
+    { url = "https://files.pythonhosted.org/packages/bb/f9/12297ed8d8301a401e7d8eb6b418d32547f1d700ed3c038d325a605421a4/numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed", size = 12560405 },
+    { url = "https://files.pythonhosted.org/packages/a7/45/7f9244cd792e163b334e3a7f02dff1239d2890b6f37ebf9e82cbe17debc0/numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f", size = 20859062 },
+    { url = "https://files.pythonhosted.org/packages/b1/b4/a084218e7e92b506d634105b13e27a3a6645312b93e1c699cc9025adb0e1/numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4", size = 13515839 },
+    { url = "https://files.pythonhosted.org/packages/27/45/58ed3f88028dcf80e6ea580311dc3edefdd94248f5770deb980500ef85dd/numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e", size = 5116031 },
+    { url = "https://files.pythonhosted.org/packages/37/a8/eb689432eb977d83229094b58b0f53249d2209742f7de529c49d61a124a0/numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0", size = 6629977 },
+    { url = "https://files.pythonhosted.org/packages/42/a3/5355ad51ac73c23334c7caaed01adadfda49544f646fcbfbb4331deb267b/numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408", size = 13575951 },
+    { url = "https://files.pythonhosted.org/packages/c4/70/ea9646d203104e647988cb7d7279f135257a6b7e3354ea6c56f8bafdb095/numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6", size = 16022655 },
+    { url = "https://files.pythonhosted.org/packages/14/ce/7fc0612903e91ff9d0b3f2eda4e18ef9904814afcae5b0f08edb7f637883/numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f", size = 16399902 },
+    { url = "https://files.pythonhosted.org/packages/ef/62/1d3204313357591c913c32132a28f09a26357e33ea3c4e2fe81269e0dca1/numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17", size = 14067180 },
+    { url = "https://files.pythonhosted.org/packages/24/d7/78a40ed1d80e23a774cb8a34ae8a9493ba1b4271dde96e56ccdbab1620ef/numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48", size = 6291907 },
+    { url = "https://files.pythonhosted.org/packages/86/09/a5ab407bd7f5f5599e6a9261f964ace03a73e7c6928de906981c31c38082/numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4", size = 12644098 },
+    { url = "https://files.pythonhosted.org/packages/00/e7/8d8bb791b62586cc432ecbb70632b4f23b7b7c88df41878de7528264f6d7/numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", size = 20983893 },
+    { url = "https://files.pythonhosted.org/packages/5e/f3/cb8118a044b5007586245a650360c9f5915b2f4232dd7658bb7a63dd1d02/numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", size = 6752501 },
+    { url = "https://files.pythonhosted.org/packages/53/f5/365b46439b518d2ec6ebb880cc0edf90f225145dfd4db7958334f7164530/numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", size = 16142601 },
+    { url = "https://files.pythonhosted.org/packages/03/c2/d1fee6ba999aa7cd41ca6856937f2baaf604c3eec1565eae63451ec31e5e/numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", size = 12771397 },
+]
+
+[[package]]
+name = "nvidia-cublas-cu12"
+version = "12.6.3.3"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/78/02/9fe3ca905d4838d716669de65006e0fb34fef7b849868f403416526f0e05/nvidia_cublas_cu12-12.6.3.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:e531199ca4f1f764fb45bc1dde49a006f6765033f9c89c737e4553b9502ca1f5", size = 390792508 },
+    { url = "https://files.pythonhosted.org/packages/f3/e7/c186a31c234fce776436753bfef4807df7f9b4cb3eeff358fcfcbf64b547/nvidia_cublas_cu12-12.6.3.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f33fb68e101d99470c82d17f92a0dd9f74de2a21685c217f4716cdd63b1316eb", size = 393135292 },
+]
+
+[[package]]
+name = "nvidia-cuda-cupti-cu12"
+version = "12.6.80"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/25/0f/acb326ac8fd26e13c799e0b4f3b2751543e1834f04d62e729485872198d4/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_aarch64.whl", hash = "sha256:358b4a1d35370353d52e12f0a7d1769fc01ff74a191689d3870b2123156184c4", size = 8236756 },
+    { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972 },
+]
+
+[[package]]
+name = "nvidia-cuda-nvcc-cu12"
+version = "12.6.77"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/01/4a/d153d4ec0bfb42889584de351dd168ebb06d293fd43b96f0d0c763b8b029/nvidia_cuda_nvcc_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9a2aad43b8f4e4be9c237ece04f64450df77871eeebffad5a5a872714a97ca77", size = 19261369 },
+    { url = "https://files.pythonhosted.org/packages/62/8f/cd3032281ba7bb531fe3159337af00c5c805fd6a31dc700f0715c8748c8c/nvidia_cuda_nvcc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b66bb5dd6b8ae62262586691977d3b4a425e91db61b4b9bc2f6b42bcd4154b96", size = 21169073 },
+]
+
+[[package]]
+name = "nvidia-cuda-runtime-cu12"
+version = "12.6.77"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/b7/3d/159023799677126e20c8fd580cca09eeb28d5c5a624adc7f793b9aa8bbfa/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d461264ecb429c84c8879a7153499ddc7b19b5f8d84c204307491989a365588e", size = 908040 },
+    { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678 },
+]
+
+[[package]]
+name = "nvidia-cudnn-cu12"
+version = "9.5.1.17"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/99/93/a201a12d3ec1caa8c6ac34c1c2f9eeb696b886f0c36ff23c638b46603bd0/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9fd4584468533c61873e5fda8ca41bac3a38bcb2d12350830c69b0a96a7e4def", size = 570523509 },
+    { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386 },
+]
+
+[[package]]
+name = "nvidia-cufft-cu12"
+version = "11.3.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/ce/f5/188566814b7339e893f8d210d3a5332352b1409815908dad6a363dcceac1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8510990de9f96c803a051822618d42bf6cb8f069ff3f48d93a8486efdacb48fb", size = 200164135 },
+    { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622 },
+]
+
+[[package]]
+name = "nvidia-cusolver-cu12"
+version = "11.7.1.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" },
+    { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/93/17/dbe1aa865e4fdc7b6d4d0dd308fdd5aaab60f939abfc0ea1954eac4fb113/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0ce237ef60acde1efc457335a2ddadfd7610b892d94efee7b776c64bb1cac9e0", size = 157833628 },
+    { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780 },
+]
+
+[[package]]
+name = "nvidia-cusparse-cu12"
+version = "12.5.4.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" },
+]
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/d3/56/3af21e43014eb40134dea004e8d0f1ef19d9596a39e4d497d5a7de01669f/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7aa32fa5470cf754f72d1116c7cbc300b4e638d3ae5304cfa4a638a5b87161b1", size = 216451135 },
+    { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357 },
+]
+
+[[package]]
+name = "nvidia-nccl-cu12"
+version = "2.23.4"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/c8/3a/0112397396dec37ffc8edd7836d48261b4d14ca60ec8ed7bc857cce1d916/nvidia_nccl_cu12-2.23.4-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa946c8327e22ced28e7cef508a334673abc42064ec85f02d005ba1785ea4cec", size = 198953892 },
+    { url = "https://files.pythonhosted.org/packages/ed/1f/6482380ec8dcec4894e7503490fc536d846b0d59694acad9cf99f27d0e7d/nvidia_nccl_cu12-2.23.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b097258d9aab2fa9f686e33c6fe40ae57b27df60cedbd15d139701bb5509e0c1", size = 198954603 },
+]
+
+[[package]]
+name = "nvidia-nvjitlink-cu12"
+version = "12.6.77"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/11/8c/386018fdffdce2ff8d43fedf192ef7d14cab7501cbf78a106dd2e9f1fc1f/nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:3bf10d85bb1801e9c894c6e197e44dd137d2a0a9e43f8450e9ad13f2df0dd52d", size = 19270432 },
+    { url = "https://files.pythonhosted.org/packages/fe/e4/486de766851d58699bcfeb3ba6a3beb4d89c3809f75b9d423b9508a8760f/nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9ae346d16203ae4ea513be416495167a0101d33d2d14935aa9c1829a3fb45142", size = 19745114 },
+]
+
+[[package]]
+name = "opt-einsum"
+version = "3.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8c/b9/2ac072041e899a52f20cf9510850ff58295003aa75525e58343591b0cbfb/opt_einsum-3.4.0.tar.gz", hash = "sha256:96ca72f1b886d148241348783498194c577fa30a8faac108586b14f1ba4473ac", size = 63004 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/23/cd/066e86230ae37ed0be70aae89aabf03ca8d9f39c8aea0dec8029455b5540/opt_einsum-3.4.0-py3-none-any.whl", hash = "sha256:69bb92469f86a1565195ece4ac0323943e83477171b91d24c35afe028a90d7cd", size = 71932 },
+]
+
+[[package]]
+name = "packaging"
+version = "24.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
+]
+
+[[package]]
+name = "pillow"
+version = "11.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/98/fb/a6ce6836bd7fd93fbf9144bf54789e02babc27403b50a9e1583ee877d6da/pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", size = 3154708 },
+    { url = "https://files.pythonhosted.org/packages/6a/1d/1f51e6e912d8ff316bb3935a8cda617c801783e0b998bf7a894e91d3bd4c/pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", size = 2979223 },
+    { url = "https://files.pythonhosted.org/packages/90/83/e2077b0192ca8a9ef794dbb74700c7e48384706467067976c2a95a0f40a1/pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", size = 4183167 },
+    { url = "https://files.pythonhosted.org/packages/0e/74/467af0146970a98349cdf39e9b79a6cc8a2e7558f2c01c28a7b6b85c5bda/pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", size = 4283912 },
+    { url = "https://files.pythonhosted.org/packages/85/b1/d95d4f7ca3a6c1ae120959605875a31a3c209c4e50f0029dc1a87566cf46/pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", size = 4195815 },
+    { url = "https://files.pythonhosted.org/packages/41/c3/94f33af0762ed76b5a237c5797e088aa57f2b7fa8ee7932d399087be66a8/pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", size = 4366117 },
+    { url = "https://files.pythonhosted.org/packages/ba/3c/443e7ef01f597497268899e1cca95c0de947c9bbf77a8f18b3c126681e5d/pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", size = 4278607 },
+    { url = "https://files.pythonhosted.org/packages/26/95/1495304448b0081e60c0c5d63f928ef48bb290acee7385804426fa395a21/pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", size = 4410685 },
+    { url = "https://files.pythonhosted.org/packages/45/da/861e1df971ef0de9870720cb309ca4d553b26a9483ec9be3a7bf1de4a095/pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", size = 2249185 },
+    { url = "https://files.pythonhosted.org/packages/d5/4e/78f7c5202ea2a772a5ab05069c1b82503e6353cd79c7e474d4945f4b82c3/pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", size = 2566726 },
+    { url = "https://files.pythonhosted.org/packages/77/e4/6e84eada35cbcc646fc1870f72ccfd4afacb0fae0c37ffbffe7f5dc24bf1/pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", size = 2254585 },
+    { url = "https://files.pythonhosted.org/packages/f0/eb/f7e21b113dd48a9c97d364e0915b3988c6a0b6207652f5a92372871b7aa4/pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", size = 3154705 },
+    { url = "https://files.pythonhosted.org/packages/25/b3/2b54a1d541accebe6bd8b1358b34ceb2c509f51cb7dcda8687362490da5b/pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", size = 2979222 },
+    { url = "https://files.pythonhosted.org/packages/20/12/1a41eddad8265c5c19dda8fb6c269ce15ee25e0b9f8f26286e6202df6693/pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", size = 4190220 },
+    { url = "https://files.pythonhosted.org/packages/a9/9b/8a8c4d07d77447b7457164b861d18f5a31ae6418ef5c07f6f878fa09039a/pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", size = 4291399 },
+    { url = "https://files.pythonhosted.org/packages/fc/e4/130c5fab4a54d3991129800dd2801feeb4b118d7630148cd67f0e6269d4c/pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", size = 4202709 },
+    { url = "https://files.pythonhosted.org/packages/39/63/b3fc299528d7df1f678b0666002b37affe6b8751225c3d9c12cf530e73ed/pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", size = 4372556 },
+    { url = "https://files.pythonhosted.org/packages/c6/a6/694122c55b855b586c26c694937d36bb8d3b09c735ff41b2f315c6e66a10/pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", size = 4287187 },
+    { url = "https://files.pythonhosted.org/packages/ba/a9/f9d763e2671a8acd53d29b1e284ca298bc10a595527f6be30233cdb9659d/pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", size = 4418468 },
+    { url = "https://files.pythonhosted.org/packages/6e/0e/b5cbad2621377f11313a94aeb44ca55a9639adabcaaa073597a1925f8c26/pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", size = 2249249 },
+    { url = "https://files.pythonhosted.org/packages/dc/83/1470c220a4ff06cd75fc609068f6605e567ea51df70557555c2ab6516b2c/pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", size = 2566769 },
+    { url = "https://files.pythonhosted.org/packages/52/98/def78c3a23acee2bcdb2e52005fb2810ed54305602ec1bfcfab2bda6f49f/pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", size = 2254611 },
+    { url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642 },
+    { url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999 },
+    { url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794 },
+    { url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762 },
+    { url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468 },
+    { url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824 },
+    { url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436 },
+    { url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714 },
+    { url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631 },
+    { url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533 },
+    { url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890 },
+    { url = "https://files.pythonhosted.org/packages/63/24/e2e15e392d00fcf4215907465d8ec2a2f23bcec1481a8ebe4ae760459995/pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", size = 3147300 },
+    { url = "https://files.pythonhosted.org/packages/43/72/92ad4afaa2afc233dc44184adff289c2e77e8cd916b3ddb72ac69495bda3/pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", size = 2978742 },
+    { url = "https://files.pythonhosted.org/packages/9e/da/c8d69c5bc85d72a8523fe862f05ababdc52c0a755cfe3d362656bb86552b/pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", size = 4194349 },
+    { url = "https://files.pythonhosted.org/packages/cd/e8/686d0caeed6b998351d57796496a70185376ed9c8ec7d99e1d19ad591fc6/pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", size = 4298714 },
+    { url = "https://files.pythonhosted.org/packages/ec/da/430015cec620d622f06854be67fd2f6721f52fc17fca8ac34b32e2d60739/pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", size = 4208514 },
+    { url = "https://files.pythonhosted.org/packages/44/ae/7e4f6662a9b1cb5f92b9cc9cab8321c381ffbee309210940e57432a4063a/pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", size = 4380055 },
+    { url = "https://files.pythonhosted.org/packages/74/d5/1a807779ac8a0eeed57f2b92a3c32ea1b696e6140c15bd42eaf908a261cd/pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", size = 4296751 },
+    { url = "https://files.pythonhosted.org/packages/38/8c/5fa3385163ee7080bc13026d59656267daaaaf3c728c233d530e2c2757c8/pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", size = 4430378 },
+    { url = "https://files.pythonhosted.org/packages/ca/1d/ad9c14811133977ff87035bf426875b93097fb50af747793f013979facdb/pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", size = 2249588 },
+    { url = "https://files.pythonhosted.org/packages/fb/01/3755ba287dac715e6afdb333cb1f6d69740a7475220b4637b5ce3d78cec2/pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", size = 2567509 },
+    { url = "https://files.pythonhosted.org/packages/c0/98/2c7d727079b6be1aba82d195767d35fcc2d32204c7a5820f822df5330152/pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", size = 2254791 },
+    { url = "https://files.pythonhosted.org/packages/eb/38/998b04cc6f474e78b563716b20eecf42a2fa16a84589d23c8898e64b0ffd/pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", size = 3150854 },
+    { url = "https://files.pythonhosted.org/packages/13/8e/be23a96292113c6cb26b2aa3c8b3681ec62b44ed5c2bd0b258bd59503d3c/pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", size = 2982369 },
+    { url = "https://files.pythonhosted.org/packages/97/8a/3db4eaabb7a2ae8203cd3a332a005e4aba00067fc514aaaf3e9721be31f1/pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", size = 4333703 },
+    { url = "https://files.pythonhosted.org/packages/28/ac/629ffc84ff67b9228fe87a97272ab125bbd4dc462745f35f192d37b822f1/pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", size = 4412550 },
+    { url = "https://files.pythonhosted.org/packages/d6/07/a505921d36bb2df6868806eaf56ef58699c16c388e378b0dcdb6e5b2fb36/pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", size = 4461038 },
+    { url = "https://files.pythonhosted.org/packages/d6/b9/fb620dd47fc7cc9678af8f8bd8c772034ca4977237049287e99dda360b66/pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", size = 2253197 },
+    { url = "https://files.pythonhosted.org/packages/df/86/25dde85c06c89d7fc5db17940f07aae0a56ac69aa9ccb5eb0f09798862a8/pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", size = 2572169 },
+    { url = "https://files.pythonhosted.org/packages/51/85/9c33f2517add612e17f3381aee7c4072779130c634921a756c97bc29fb49/pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", size = 2256828 },
+    { url = "https://files.pythonhosted.org/packages/36/57/42a4dd825eab762ba9e690d696d894ba366e06791936056e26e099398cda/pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", size = 3119239 },
+    { url = "https://files.pythonhosted.org/packages/98/f7/25f9f9e368226a1d6cf3507081a1a7944eddd3ca7821023377043f5a83c8/pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", size = 2950803 },
+    { url = "https://files.pythonhosted.org/packages/59/01/98ead48a6c2e31e6185d4c16c978a67fe3ccb5da5c2ff2ba8475379bb693/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", size = 3281098 },
+    { url = "https://files.pythonhosted.org/packages/51/c0/570255b2866a0e4d500a14f950803a2ec273bac7badc43320120b9262450/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", size = 3323665 },
+    { url = "https://files.pythonhosted.org/packages/0e/75/689b4ec0483c42bfc7d1aacd32ade7a226db4f4fac57c6fdcdf90c0731e3/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", size = 3310533 },
+    { url = "https://files.pythonhosted.org/packages/3d/30/38bd6149cf53da1db4bad304c543ade775d225961c4310f30425995cb9ec/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", size = 3414886 },
+    { url = "https://files.pythonhosted.org/packages/ec/3d/c32a51d848401bd94cabb8767a39621496491ee7cd5199856b77da9b18ad/pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", size = 2567508 },
+]
+
+[[package]]
+name = "pyparsing"
+version = "3.2.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8c/d5/e5aeee5387091148a19e1145f63606619cb5f20b83fccb63efae6474e7b2/pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c", size = 920984 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", size = 106921 },
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
+]
+
+[[package]]
+name = "ruff"
+version = "0.7.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/4b/06/09d1276df977eece383d0ed66052fc24ec4550a61f8fbc0a11200e690496/ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313", size = 3243664 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/c0/56/933d433c2489e4642487b835f53dd9ff015fb3d8fa459b09bb2ce42d7c4b/ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344", size = 10372090 },
+    { url = "https://files.pythonhosted.org/packages/20/ea/1f0a22a6bcdd3fc26c73f63a025d05bd565901b729d56bcb093c722a6c4c/ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0", size = 10190037 },
+    { url = "https://files.pythonhosted.org/packages/16/74/aca75666e0d481fe394e76a8647c44ea919087748024924baa1a17371e3e/ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9", size = 9811998 },
+    { url = "https://files.pythonhosted.org/packages/20/a1/cf446a0d7f78ea1f0bd2b9171c11dfe746585c0c4a734b25966121eb4f5d/ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5", size = 10620626 },
+    { url = "https://files.pythonhosted.org/packages/cd/c1/82b27d09286ae855f5d03b1ad37cf243f21eb0081732d4d7b0d658d439cb/ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299", size = 10177598 },
+    { url = "https://files.pythonhosted.org/packages/b9/42/c0acac22753bf74013d035a5ef6c5c4c40ad4d6686bfb3fda7c6f37d9b37/ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e", size = 11171963 },
+    { url = "https://files.pythonhosted.org/packages/43/18/bb0befb7fb9121dd9009e6a72eb98e24f1bacb07c6f3ecb55f032ba98aed/ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29", size = 11856157 },
+    { url = "https://files.pythonhosted.org/packages/5e/91/04e98d7d6e32eca9d1372be595f9abc7b7f048795e32eb2edbd8794d50bd/ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5", size = 11440331 },
+    { url = "https://files.pythonhosted.org/packages/f5/dc/3fe99f2ce10b76d389041a1b9f99e7066332e479435d4bebcceea16caff5/ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67", size = 12725354 },
+    { url = "https://files.pythonhosted.org/packages/43/7b/1daa712de1c5bc6cbbf9fa60e9c41cc48cda962dc6d2c4f2a224d2c3007e/ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2", size = 11010091 },
+    { url = "https://files.pythonhosted.org/packages/b6/db/1227a903587432eb569e57a95b15a4f191a71fe315cde4c0312df7bc85da/ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d", size = 10610687 },
+    { url = "https://files.pythonhosted.org/packages/db/e2/dc41ee90c3085aadad4da614d310d834f641aaafddf3dfbba08210c616ce/ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2", size = 10254843 },
+    { url = "https://files.pythonhosted.org/packages/6f/09/5f6cac1c91542bc5bd33d40b4c13b637bf64d7bb29e091dadb01b62527fe/ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2", size = 10730962 },
+    { url = "https://files.pythonhosted.org/packages/d3/42/89a4b9a24ef7d00269e24086c417a006f9a3ffeac2c80f2629eb5ce140ee/ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16", size = 11101907 },
+    { url = "https://files.pythonhosted.org/packages/b0/5c/efdb4777686683a8edce94ffd812783bddcd3d2454d38c5ac193fef7c500/ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc", size = 8611095 },
+    { url = "https://files.pythonhosted.org/packages/bb/b8/28fbc6a4efa50178f973972d1c84b2d0a33cdc731588522ab751ac3da2f5/ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088", size = 9418283 },
+    { url = "https://files.pythonhosted.org/packages/3f/77/b587cba6febd5e2003374f37eb89633f79f161e71084f94057c8653b7fb3/ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c", size = 8725228 },
+]
+
+[[package]]
+name = "scipy"
+version = "1.14.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/64/68/3bc0cfaf64ff507d82b1e5d5b64521df4c8bf7e22bc0b897827cbee9872c/scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389", size = 39069598 },
+    { url = "https://files.pythonhosted.org/packages/43/a5/8d02f9c372790326ad405d94f04d4339482ec082455b9e6e288f7100513b/scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3", size = 29879676 },
+    { url = "https://files.pythonhosted.org/packages/07/42/0e0bea9666fcbf2cb6ea0205db42c81b1f34d7b729ba251010edf9c80ebd/scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0", size = 23088696 },
+    { url = "https://files.pythonhosted.org/packages/15/47/298ab6fef5ebf31b426560e978b8b8548421d4ed0bf99263e1eb44532306/scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3", size = 25470699 },
+    { url = "https://files.pythonhosted.org/packages/d8/df/cdb6be5274bc694c4c22862ac3438cb04f360ed9df0aecee02ce0b798380/scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d", size = 35606631 },
+    { url = "https://files.pythonhosted.org/packages/47/78/b0c2c23880dd1e99e938ad49ccfb011ae353758a2dc5ed7ee59baff684c3/scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69", size = 41178528 },
+    { url = "https://files.pythonhosted.org/packages/5d/aa/994b45c34b897637b853ec04334afa55a85650a0d11dacfa67232260fb0a/scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad", size = 42784535 },
+    { url = "https://files.pythonhosted.org/packages/e7/1c/8daa6df17a945cb1a2a1e3bae3c49643f7b3b94017ff01a4787064f03f84/scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5", size = 44772117 },
+    { url = "https://files.pythonhosted.org/packages/b2/ab/070ccfabe870d9f105b04aee1e2860520460ef7ca0213172abfe871463b9/scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675", size = 39076999 },
+    { url = "https://files.pythonhosted.org/packages/a7/c5/02ac82f9bb8f70818099df7e86c3ad28dae64e1347b421d8e3adf26acab6/scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2", size = 29894570 },
+    { url = "https://files.pythonhosted.org/packages/ed/05/7f03e680cc5249c4f96c9e4e845acde08eb1aee5bc216eff8a089baa4ddb/scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617", size = 23103567 },
+    { url = "https://files.pythonhosted.org/packages/5e/fc/9f1413bef53171f379d786aabc104d4abeea48ee84c553a3e3d8c9f96a9c/scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8", size = 25499102 },
+    { url = "https://files.pythonhosted.org/packages/c2/4b/b44bee3c2ddc316b0159b3d87a3d467ef8d7edfd525e6f7364a62cd87d90/scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37", size = 35586346 },
+    { url = "https://files.pythonhosted.org/packages/93/6b/701776d4bd6bdd9b629c387b5140f006185bd8ddea16788a44434376b98f/scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2", size = 41165244 },
+    { url = "https://files.pythonhosted.org/packages/06/57/e6aa6f55729a8f245d8a6984f2855696c5992113a5dc789065020f8be753/scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2", size = 42817917 },
+    { url = "https://files.pythonhosted.org/packages/ea/c2/5ecadc5fcccefaece775feadcd795060adf5c3b29a883bff0e678cfe89af/scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94", size = 44781033 },
+    { url = "https://files.pythonhosted.org/packages/c0/04/2bdacc8ac6387b15db6faa40295f8bd25eccf33f1f13e68a72dc3c60a99e/scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d", size = 39128781 },
+    { url = "https://files.pythonhosted.org/packages/c8/53/35b4d41f5fd42f5781dbd0dd6c05d35ba8aa75c84ecddc7d44756cd8da2e/scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07", size = 29939542 },
+    { url = "https://files.pythonhosted.org/packages/66/67/6ef192e0e4d77b20cc33a01e743b00bc9e68fb83b88e06e636d2619a8767/scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5", size = 23148375 },
+    { url = "https://files.pythonhosted.org/packages/f6/32/3a6dedd51d68eb7b8e7dc7947d5d841bcb699f1bf4463639554986f4d782/scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc", size = 25578573 },
+    { url = "https://files.pythonhosted.org/packages/f0/5a/efa92a58dc3a2898705f1dc9dbaf390ca7d4fba26d6ab8cfffb0c72f656f/scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310", size = 35319299 },
+    { url = "https://files.pythonhosted.org/packages/8e/ee/8a26858ca517e9c64f84b4c7734b89bda8e63bec85c3d2f432d225bb1886/scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066", size = 40849331 },
+    { url = "https://files.pythonhosted.org/packages/a5/cd/06f72bc9187840f1c99e1a8750aad4216fc7dfdd7df46e6280add14b4822/scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1", size = 42544049 },
+    { url = "https://files.pythonhosted.org/packages/aa/7d/43ab67228ef98c6b5dd42ab386eae2d7877036970a0d7e3dd3eb47a0d530/scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f", size = 44521212 },
+    { url = "https://files.pythonhosted.org/packages/50/ef/ac98346db016ff18a6ad7626a35808f37074d25796fd0234c2bb0ed1e054/scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79", size = 39091068 },
+    { url = "https://files.pythonhosted.org/packages/b9/cc/70948fe9f393b911b4251e96b55bbdeaa8cca41f37c26fd1df0232933b9e/scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e", size = 29875417 },
+    { url = "https://files.pythonhosted.org/packages/3b/2e/35f549b7d231c1c9f9639f9ef49b815d816bf54dd050da5da1c11517a218/scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73", size = 23084508 },
+    { url = "https://files.pythonhosted.org/packages/3f/d6/b028e3f3e59fae61fb8c0f450db732c43dd1d836223a589a8be9f6377203/scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e", size = 25503364 },
+    { url = "https://files.pythonhosted.org/packages/a7/2f/6c142b352ac15967744d62b165537a965e95d557085db4beab2a11f7943b/scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d", size = 35292639 },
+    { url = "https://files.pythonhosted.org/packages/56/46/2449e6e51e0d7c3575f289f6acb7f828938eaab8874dbccfeb0cd2b71a27/scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e", size = 40798288 },
+    { url = "https://files.pythonhosted.org/packages/32/cd/9d86f7ed7f4497c9fd3e39f8918dd93d9f647ba80d7e34e4946c0c2d1a7c/scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06", size = 42524647 },
+    { url = "https://files.pythonhosted.org/packages/f5/1b/6ee032251bf4cdb0cc50059374e86a9f076308c1512b61c4e003e241efb7/scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84", size = 44469524 },
+]
+
+[[package]]
+name = "setuptools"
+version = "75.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ed/22/a438e0caa4576f8c383fa4d35f1cc01655a46c75be358960d815bfbb12bd/setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686", size = 1351577 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/90/12/282ee9bce8b58130cb762fbc9beabd531549952cac11fc56add11dcb7ea0/setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", size = 1251070 },
+]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 },
+]
+
+[[package]]
+name = "toolz"
+version = "1.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8a/0b/d80dfa675bf592f636d1ea0b835eab4ec8df6e9415d8cfd766df54456123/toolz-1.0.0.tar.gz", hash = "sha256:2c86e3d9a04798ac556793bced838816296a2f085017664e4995cb40a1047a02", size = 66790 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/03/98/eb27cc78ad3af8e302c9d8ff4977f5026676e130d28dd7578132a457170c/toolz-1.0.0-py3-none-any.whl", hash = "sha256:292c8f1c4e7516bf9086f8850935c799a874039c8bcf959d47b600e4c44a6236", size = 56383 },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
+]
+
+[[package]]
+name = "xraylib"
+version = "4.1.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/4c/cc/f4d2c3231a256f62938fafbf42e487554fb4a83ab50a55e16be26cec468f/xraylib-4.1.5.tar.gz", hash = "sha256:0806b009a25288711cf7cc96fad61dbedd5668819562837d12ea8fe01343bfc1", size = 13204048 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/02/a5/ae97d11e2b73bf249e94a235464cb60f6939546fec1d0196f6c380d94d85/xraylib-4.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:325598da5ca8c1c33f6aa311c97d4a2bf4eaa0573f8a72486fe5b0c6a9ee5e5d", size = 16007436 },
+    { url = "https://files.pythonhosted.org/packages/1a/a3/98cbd66c0cc866798687fa7cf71bc2b66ce97d88197ec0030047e4e2f0fc/xraylib-4.1.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e10a3c04effb88b0ac99a0504f868645c5fc6ac5303c9d3541085456d233079", size = 16221877 },
+    { url = "https://files.pythonhosted.org/packages/40/77/a008bbf39a3398cb96c635efd8d3dd6b7ac42ad1ef94432c7b37b1ee7fe0/xraylib-4.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8824ec9d880fbd37d6f166114853bca82b6f5282c1df3163e3834b581366004d", size = 16356892 },
+    { url = "https://files.pythonhosted.org/packages/f2/62/1e9148d2470beb1b3652c0775255f25f1c0afce02cf97d4a30b31db11a78/xraylib-4.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:508d263eeccf2a05a73cb7b4bf5d6568aa36f0982b9457b33a05df29d2590380", size = 14941025 },
+    { url = "https://files.pythonhosted.org/packages/7a/33/69d6c1c11a61ed147959e71dddcc3cb0f351773bcd2497de197483626052/xraylib-4.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e514d7063dd0483aa675f2895db90522aa54ef88744bdc47b05ccaffa3df16cb", size = 16009809 },
+    { url = "https://files.pythonhosted.org/packages/97/62/e14a4bc10af803f33052dd1d9bc65cd6bdcf28509e41ac938def376e3b9f/xraylib-4.1.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4d35c48bdc7aa851895e4f9dafb3cf2fdae9d0343504cf386f985c531f17348", size = 16222959 },
+    { url = "https://files.pythonhosted.org/packages/7d/af/42d63aebf5130f9e60aeb2d5a4a3ad50f6b5c5fc7a0ba414948dd24e8961/xraylib-4.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e1e95564ef63f2948884cdc4a7a836667c2d1bc0c9f5a38961d5776a02c3387", size = 16360052 },
+    { url = "https://files.pythonhosted.org/packages/56/bc/ec7a2a8bde475322b21fd953cac0bdb74404f13bbd8beb69c57fad475336/xraylib-4.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:b62de1b7e4a20f523cdc4a274a9b5f7dc196fbe4e206d93d9d8915682beec365", size = 14941442 },
+    { url = "https://files.pythonhosted.org/packages/17/c1/471708d615351b1e6639e4237cc86290c4c09a475cb823c8d8cd675491fc/xraylib-4.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b3829a98de42cfe31b073ea57c0ac7a8eff36fda9597437ffca27bc10fa476b", size = 16009191 },
+    { url = "https://files.pythonhosted.org/packages/05/5c/f5cdea6f822116868183e7004bacc297e4fa3f89324dee53c80b055808ce/xraylib-4.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a6ce16bffeebd42cfe83f43694b51174c69b3f01430e235109293903a7f97090", size = 16227522 },
+    { url = "https://files.pythonhosted.org/packages/f8/76/1cc6ba2bb9d0e16eefcd04e188f08e8b1c4ddf4e43ba1e36807c58d2bc3e/xraylib-4.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c368962fe38126c445e2c1c0f2899c38f0593ba5d66657c2b01437759a0739aa", size = 16348727 },
+    { url = "https://files.pythonhosted.org/packages/b2/cd/2e4e63e50ad81400d40df19f41992bb8ab9b374307ad4e1eaaa59481b9f3/xraylib-4.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:1102b6dfa6e761de3cb36b717559a55c76995000bd0b66d26d05d122978f4e5e", size = 14945070 },
+    { url = "https://files.pythonhosted.org/packages/fb/0f/3b0cf048a1f11142f45c9f675c8d6fbac710b577cc21477d7087e8639d5c/xraylib-4.1.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25b4291679fa9b83b99c4aed3afcda966456fb686bfa49a75652f087ffc3a2cc", size = 16008267 },
+    { url = "https://files.pythonhosted.org/packages/f1/5a/d18483ff841ebe38e711444c99d83965401f42c00d16b6375e6a6c84caf0/xraylib-4.1.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:41d760879012628051968bcfe1fc2b1373d69356b5d134f78cf5171b7f1c7971", size = 16226937 },
+    { url = "https://files.pythonhosted.org/packages/52/c8/1b2ad0f1033ab0da1d8d616ea8f753b1de895834f8cbf4c66aef9e7913fc/xraylib-4.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f9b30a65368df889ff29929993d05abe16ed3e12ff1828e3d8cb5cd1661e84", size = 16350395 },
+    { url = "https://files.pythonhosted.org/packages/8c/f9/a73c6b403e463ea8c648ffb01e764e913e300e47769ca528a0fd11bc91c3/xraylib-4.1.5-cp313-cp313-win_amd64.whl", hash = "sha256:0adcf21c5f94fc2456f115e74d59f8fe97394a1e762296a6616483a52c896388", size = 14945316 },
+]