From 603a4e74b601efffd1457d637d1f62e7bad4c901 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 1 Nov 2025 16:54:56 +0100 Subject: [PATCH 001/107] feat: rajout de lidar.stop dans car.stop() et de multiprocessus dans main --- src/HL/Car.py | 3 ++- src/HL/main.py | 58 +++++++++++++++++++++++--------------------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/HL/Car.py b/src/HL/Car.py index 78ab987b..c01054a3 100644 --- a/src/HL/Car.py +++ b/src/HL/Car.py @@ -26,7 +26,7 @@ def __init__(self, driver): """Initialize the car's components.""" self.vitesse_milimetres_s = 0 # Speed in millimeters per second self.angle_degre = 0 # Steering angle in degrees - + def _initialize_speed_limits(): """Set the car's speed limits.""" self.vitesse_max_m_s_hard = 6000 # Maximum hardware speed @@ -108,6 +108,7 @@ def stop(self): self.vitesse_milimetres_s = 0 self.angle_degre = 0 write_vitesse_direction(self.vitesse_milimetres_s, self.angle_degre) #stop the car + self.lidar.stop() def has_Crashed(self): diff --git a/src/HL/main.py b/src/HL/main.py index 84e89e4b..ee96d09f 100644 --- a/src/HL/main.py +++ b/src/HL/main.py @@ -2,8 +2,6 @@ # 0 - Idle # 1 - Auto Driving # 2 - Manual Driving with ps4 controller -# 3 - tune prop_pwm -# 4 - tune dir_pwm from gpiozero import LED, Button, Buzzer from luma.core.interface.serial import i2c @@ -16,11 +14,17 @@ from get_ip import get_ip, check_ssh_connections +from multiprocessing import Processus #pour pouvoir lancer les programme sur un cpu différent + bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 #oled serial = i2c(port=1, address=0x3C) device = ssd1306(serial) +auto_driving_p = Process(target=Auto_Driving) +manual_driving_p = Process(target=Manual_Driving) + +list_p = [auto_driving_p,manual_driving_p] #liste tout les processus possible SLAVE_ADDRESS = 0x08 # I2C address of the slave arduino or stm32 bp_next = Button("GPIO5", bounce_time=0.1) @@ -107,25 +111,36 @@ def Idle(): #Enable chossing between states case 2: #Manual Driving mode text = "Manual Driving With PS4 Controller" #PS4 controller status - case 3: #tune prop_pwm - text = "Tune Prop PWM" - #PS4 controller status - - case 4: #tune dir_pwm - text = "Tune Dir PWM" - #PS4 controller status + case 3: #Kill all processus + text = "Kill all the process" + if (State==Screen): + text+=": (en cours)" + display_combined_im(text) + + if bp_next.is_pressed: bp_next.wait_for_release() Screen+=1 - if Screen>4: + if Screen>len(list_p): Screen=0 if bp_entre.is_pressed: bp_entre.wait_for_release() State=Screen + p_choisie(State-1) # -1 because of the process cases begin at 1 and the list_p indexe at 0 - +def p_choisie(p_id): + """ Kill tout les processus et lance celui choisie par p_id dans la liste list_p + (Donner un p_id plus grand que len(list_p) tue tout les processus + """ + for i in range(len(list_p)): + if (i!= p_id): + list_p[i].terminate() + + if (p_id Date: Wed, 5 Nov 2025 21:59:32 +0100 Subject: [PATCH 002/107] =?UTF-8?q?Ajout=20du=20serveur=20a=20la=20branch?= =?UTF-8?q?=20main=20manager.=20Attention=20pas=20encore=20eu=20la=20modif?= =?UTF-8?q?=20de=20la=20classe=20camera=20donc=20en=20l'etat=20possible=20?= =?UTF-8?q?probleme=20avec=20les=20fonctions=20li=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/HL/Serveur.py diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py new file mode 100644 index 00000000..337c35b3 --- /dev/null +++ b/src/HL/Serveur.py @@ -0,0 +1,99 @@ +import time +import logging +import sys +from systemd.journal import JournaldLogHandler +import zerorpc +import struct +import logging as log + +from Camera import Camera +import smbus #type: ignore +""" +Lancer un serveur qui tourne h24 qui gere l'intercommunication des processus (qui sont externe a la Pi) +Cf envoie vitesse a l'arduino, communication avec l'ecran , avec les boutons ,avec le lidar et la camera +Tout doit passer par cette classe qui tourne s +""" + +bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 + +# I2C address of the slave +SLAVE_ADDRESS = 0x08 + + +vitesse = 200 # en millimetre par seconde +direction = 100 # en degré + + +class ApiVoiture(): # pylint: disable=too-few-public-methods + """ + ça controlera tout + """ + + def __init__(self): + log.basicConfig(level=log.INFO) # Mettre log.DEBUG pour plus de détails + log.info("Initialisation de la caméra...") + self.cam = Camera() + log.info("Caméra initialisée.") + log.info("Démarrage du thread de capture...") + cam.start() + log.info("Thread de capture démarré.") + + def write_vitesse_direction(self,vitesse, direction): + # Convert string to list of ASCII values + data = struct.pack('= 4: + float_value = struct.unpack('f', bytes(data[:4]))[0] + return float_value + else: + raise ValueError("Not enough data received from I2C bus") + + def lire_donnees_arduino(self): + """ + Lit huit octets de l'Arduino et les convertit en 2 float. + On veut la vitesse reel et la vitesse cible + """ + try: + # Demande 8 octets à l'esclave. + data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, 8) + # Reconstituer les entiers + vitesse_reel = struct.unpack(' Date: Thu, 6 Nov 2025 23:54:52 +0100 Subject: [PATCH 003/107] creation de test_serveur pour tester la communication zerorpc --- src/HL/Serveur.py | 4 ++-- src/HL/test_serveur.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/HL/test_serveur.py diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 337c35b3..028d6114 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -20,8 +20,6 @@ SLAVE_ADDRESS = 0x08 -vitesse = 200 # en millimetre par seconde -direction = 100 # en degré class ApiVoiture(): # pylint: disable=too-few-public-methods @@ -30,6 +28,8 @@ class ApiVoiture(): # pylint: disable=too-few-public-methods """ def __init__(self): + self.vitesse = 0 #vitesse en metre par seconde + self.direction = 0 # direction en degrés avec 0 le degré du centre log.basicConfig(level=log.INFO) # Mettre log.DEBUG pour plus de détails log.info("Initialisation de la caméra...") self.cam = Camera() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py new file mode 100644 index 00000000..180ca0bb --- /dev/null +++ b/src/HL/test_serveur.py @@ -0,0 +1,18 @@ +import zerorpc + +IP_DU_RASPBERRY_PI = "192.168.1.25" + +c = zerorpc.Client() +c.connect(f"tcp://{IP_DU_RASPBERRY_PI}:4242") + + +if __name__ == "__main__": + while(True): + vitesse= float(input("vitesse en millimetre par seconde:")) + rotation= float(input("rotation en degré:")) + c.write_vitesse_direction(vitesse,rotation) + time.sleep(0.1) # Wait for the slave to process the data + received = c.read_data(8) # Adjust length as needed + print("Received from slave:", received) + + # Request data from the slave \ No newline at end of file From 895f19bb436bf342f710336e8e6bdf6140fbee4f Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 12 Nov 2025 23:34:04 +0100 Subject: [PATCH 004/107] feat: rajout des constantes vitesse et direction dans la classe apivoiture --- src/HL/Serveur.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 028d6114..f5b961e5 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -37,6 +37,8 @@ def __init__(self): log.info("Démarrage du thread de capture...") cam.start() log.info("Thread de capture démarré.") + self.vitesse_m_s = 0 + self.direction = 0 def write_vitesse_direction(self,vitesse, direction): # Convert string to list of ASCII values From c2e72cb6a68be4fb055fa43ae48b3b5242d94cd1 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 12 Nov 2025 23:48:17 +0100 Subject: [PATCH 005/107] fix : journal handler name --- To | 0 src/HL/Serveur.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 To diff --git a/To b/To new file mode 100644 index 00000000..e69de29b diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index f5b961e5..93060b7a 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -1,7 +1,7 @@ import time import logging import sys -from systemd.journal import JournaldLogHandler +from systemd.journal import JournalHandler import zerorpc import struct import logging as log From caacc488f2b015a9318d70b63939039804243a68 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:15:46 +0100 Subject: [PATCH 006/107] =?UTF-8?q?feat:=20rajout=20des=20d=C3=A9pendence?= =?UTF-8?q?=20dans=20le=20Serveur=20en=20attendant=20de=20le=20rajouter=20?= =?UTF-8?q?dans=20la=20doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 93060b7a..6c42eb37 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -8,6 +8,10 @@ from Camera import Camera import smbus #type: ignore + +# uv pip install systemd-python +# uv pip install picamera2 +# sudo apt install python3-libcamera """ Lancer un serveur qui tourne h24 qui gere l'intercommunication des processus (qui sont externe a la Pi) Cf envoie vitesse a l'arduino, communication avec l'ecran , avec les boutons ,avec le lidar et la camera @@ -98,4 +102,5 @@ def gen_frames(self): s = zerorpc.Server(ApiVoiture()) s.bind("tcp://0.0.0.0:4242") - s.run() \ No newline at end of file + s.run() + print("ok?") \ No newline at end of file From 2a05b381e0055380fa512b4641216551602bca4c Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:16:31 +0100 Subject: [PATCH 007/107] =?UTF-8?q?feat=20:=20rajout=20de=20test=20pour=20?= =?UTF-8?q?v=C3=A9rifier=20si=20le=20serveur=20est=20lanc=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 6c42eb37..63916f52 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -102,5 +102,6 @@ def gen_frames(self): s = zerorpc.Server(ApiVoiture()) s.bind("tcp://0.0.0.0:4242") + print("serveur lancé?") s.run() print("ok?") \ No newline at end of file From f536c1a99a37b45e20af2bd3db586eacce914b68 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:17:38 +0100 Subject: [PATCH 008/107] fix : self.cam.start --- src/HL/Serveur.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 63916f52..7c3309d3 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -39,7 +39,7 @@ def __init__(self): self.cam = Camera() log.info("Caméra initialisée.") log.info("Démarrage du thread de capture...") - cam.start() + self.cam.start() log.info("Thread de capture démarré.") self.vitesse_m_s = 0 self.direction = 0 From ed661949d52180bf813de4c6498c5f8e2689caaa Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:18:37 +0100 Subject: [PATCH 009/107] rajouut de try et de exception pour voir les erreur --- src/HL/Serveur.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 7c3309d3..b9572154 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -100,8 +100,11 @@ def gen_frames(self): if __name__ == '__main__': - s = zerorpc.Server(ApiVoiture()) - s.bind("tcp://0.0.0.0:4242") - print("serveur lancé?") - s.run() - print("ok?") \ No newline at end of file + try: + api = ApiVoiture() + s = zerorpc.Server(api) + s.bind("tcp://0.0.0.0:4242") + print("Serveur ZERORPC lancé sur tcp://0.0.0.0:4242") + s.run() + except Exception as e: + print("Erreur au démarrage :", e) \ No newline at end of file From 3a9d1e33105b5282e7b96d9e1d8311d371da9381 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:19:03 +0100 Subject: [PATCH 010/107] =?UTF-8?q?rajout=20de=20test=20au=20d=C3=A9but?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index b9572154..42097409 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -24,7 +24,7 @@ SLAVE_ADDRESS = 0x08 - +print("lancement...") class ApiVoiture(): # pylint: disable=too-few-public-methods """ From d0116d13be85b11f97a731656ef77eb46501bff7 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 00:19:52 +0100 Subject: [PATCH 011/107] test --- src/HL/Serveur.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 42097409..8648a44e 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -1,3 +1,4 @@ +print("lancement...?") import time import logging import sys From 7cdc0e2ceecabbf2f7149e90875866b04ac58f74 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 17:35:31 +0100 Subject: [PATCH 012/107] fix : enlevage de system car pas important pour l'instant --- src/HL/Serveur.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 8648a44e..e9abf753 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -2,7 +2,7 @@ import time import logging import sys -from systemd.journal import JournalHandler +# from systemd.journal import JournalHandler #il y a des soucis dessus pour linstant import zerorpc import struct import logging as log From 12b0e4d7bc81d3007a71553d97cb9102dbdd9ff9 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 17:38:13 +0100 Subject: [PATCH 013/107] fix : enlevage de picamera en attendant de test zerorpc --- src/HL/Serveur.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index e9abf753..c9b4dd6b 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -7,7 +7,7 @@ import struct import logging as log -from Camera import Camera +# from Camera import Camera import smbus #type: ignore # uv pip install systemd-python @@ -37,10 +37,10 @@ def __init__(self): self.direction = 0 # direction en degrés avec 0 le degré du centre log.basicConfig(level=log.INFO) # Mettre log.DEBUG pour plus de détails log.info("Initialisation de la caméra...") - self.cam = Camera() + # self.cam = Camera() log.info("Caméra initialisée.") log.info("Démarrage du thread de capture...") - self.cam.start() + # self.cam.start() log.info("Thread de capture démarré.") self.vitesse_m_s = 0 self.direction = 0 From d0597c09672ecf2179d30225ae1219ee725bcc59 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 18:02:34 +0100 Subject: [PATCH 014/107] test --- src/HL/Serveur.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index c9b4dd6b..71dc434d 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -47,6 +47,7 @@ def __init__(self): def write_vitesse_direction(self,vitesse, direction): # Convert string to list of ASCII values + print("write_vitesse_direction") data = struct.pack(' Date: Thu, 13 Nov 2025 18:02:37 +0100 Subject: [PATCH 015/107] test --- src/HL/test_serveur.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 180ca0bb..18bde464 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -1,9 +1,8 @@ import zerorpc - -IP_DU_RASPBERRY_PI = "192.168.1.25" +import time c = zerorpc.Client() -c.connect(f"tcp://{IP_DU_RASPBERRY_PI}:4242") +c.connect(f"tcp://0.0.0.0:4242") if __name__ == "__main__": From 7bd711850c76876fd201b8b157f934931449aa07 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 18:05:13 +0100 Subject: [PATCH 016/107] fix: on passe a une meilleur structure de read_data fait par l'asserv et on regle des soucis de ip --- src/HL/Serveur.py | 13 ++++++++----- src/HL/masterI2C.py | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 71dc434d..6174bd67 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -51,13 +51,16 @@ def write_vitesse_direction(self,vitesse, direction): data = struct.pack('= 4: - float_value = struct.unpack('f', bytes(data[:4]))[0] - return float_value + # Convert the byte data to floats + if len(data) >= length: + float_values = struct.unpack('f' * num_floats, bytes(data[:length])) + return list(float_values) else: raise ValueError("Not enough data received from I2C bus") diff --git a/src/HL/masterI2C.py b/src/HL/masterI2C.py index 5a3f6800..5cc20efb 100644 --- a/src/HL/masterI2C.py +++ b/src/HL/masterI2C.py @@ -38,8 +38,8 @@ def read_data(length): rotation= float(input("rotation en degré:")) write_vitesse_direction(vitesse,rotation) time.sleep(0.1) # Wait for the slave to process the data - received = read_data(8) # Adjust length as needed - print("Received from slave:", received) + received = read_data(3) # Adjust length as needed + print("Received from slave:", received[0], received[1], received[2] ) # Request data from the slave \ No newline at end of file From 88a16ce7c426e85acedc8391a290690a336e1e43 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 18:07:34 +0100 Subject: [PATCH 017/107] changement dans test_serveur --- src/HL/test_serveur.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 18bde464..d9a32ab5 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -11,7 +11,7 @@ rotation= float(input("rotation en degré:")) c.write_vitesse_direction(vitesse,rotation) time.sleep(0.1) # Wait for the slave to process the data - received = c.read_data(8) # Adjust length as needed - print("Received from slave:", received) + received = read_data(3) # Adjust length as needed + print("Received from slave:", received[0], received[1], received[2] ) # Request data from the slave \ No newline at end of file From b16f35f212beb84d76fb79676a0fb57e7a0c0a1b Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 18:10:21 +0100 Subject: [PATCH 018/107] =?UTF-8?q?fix:=20dans=20read=5Fdata=20oublie=20de?= =?UTF-8?q?=20self=20et=20rajout=20de=20la=20mise=20=C3=A0=20jour=20de=20l?= =?UTF-8?q?a=20vitesse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 6 ++++-- src/HL/test_serveur.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 6174bd67..1f3077ab 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -51,7 +51,7 @@ def write_vitesse_direction(self,vitesse, direction): data = struct.pack('= length: float_values = struct.unpack('f' * num_floats, bytes(data[:length])) - return list(float_values) + list_valeur = list(float_values) + self.vitesse = list_valeur[2] + return list_valeur else: raise ValueError("Not enough data received from I2C bus") diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index d9a32ab5..4547d486 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -11,7 +11,7 @@ rotation= float(input("rotation en degré:")) c.write_vitesse_direction(vitesse,rotation) time.sleep(0.1) # Wait for the slave to process the data - received = read_data(3) # Adjust length as needed + received = c.read_data(3) # Adjust length as needed print("Received from slave:", received[0], received[1], received[2] ) # Request data from the slave \ No newline at end of file From 9556f2b6f6cec8355103f88514045ba0825a3170 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 13 Nov 2025 19:23:23 +0100 Subject: [PATCH 019/107] =?UTF-8?q?feat=20:=20enlevage=20des=20print=20inu?= =?UTF-8?q?tile=20et=20rajout=20de=20variable=20pour=20enregistrer=20les?= =?UTF-8?q?=20=C3=A9tat=20actuel=20de=20la=20voiture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index 1f3077ab..c25ed8f9 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -1,4 +1,3 @@ -print("lancement...?") import time import logging import sys @@ -25,16 +24,17 @@ SLAVE_ADDRESS = 0x08 -print("lancement...") - class ApiVoiture(): # pylint: disable=too-few-public-methods """ ça controlera tout """ def __init__(self): - self.vitesse = 0 #vitesse en metre par seconde + self.vitesse_r = 0 # vitesse en metre par seconde réel + self.vitesse_d = 0 # vitesse demander en metre par seconde self.direction = 0 # direction en degrés avec 0 le degré du centre + self.voltage_lipo = 0 + self.voltage_nimh = 0 log.basicConfig(level=log.INFO) # Mettre log.DEBUG pour plus de détails log.info("Initialisation de la caméra...") # self.cam = Camera() @@ -46,8 +46,10 @@ def __init__(self): self.direction = 0 def write_vitesse_direction(self,vitesse, direction): - # Convert string to list of ASCII values - print("write_vitesse_direction") + + self.vitesse_d = vitesse #on enregistre la vitesse demandé + self.direction = direction # on enregistre la direction voulue + data = struct.pack('= length: float_values = struct.unpack('f' * num_floats, bytes(data[:length])) list_valeur = list(float_values) - self.vitesse = list_valeur[2] + + # on enregistre les valeur + self.voltage_lipo = list_valeur[0] + self.voltage_nimh = list_valeur[1] + self.vitesse_r = list_valeur[2] + return list_valeur else: raise ValueError("Not enough data received from I2C bus") - def lire_donnees_arduino(self): - """ - Lit huit octets de l'Arduino et les convertit en 2 float. - On veut la vitesse reel et la vitesse cible - """ - try: - # Demande 8 octets à l'esclave. - data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, 8) - # Reconstituer les entiers - vitesse_reel = struct.unpack(' Date: Sat, 15 Nov 2025 01:17:13 +0100 Subject: [PATCH 020/107] feat : rajout de test serveru avec la nouvelle structure de zeromq --- src/HL/Serveur.py | 1 - src/HL/Serveur_mq.py | 84 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/HL/Serveur_mq.py diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py index c25ed8f9..c37614fe 100644 --- a/src/HL/Serveur.py +++ b/src/HL/Serveur.py @@ -1,5 +1,4 @@ import time -import logging import sys # from systemd.journal import JournalHandler #il y a des soucis dessus pour linstant import zerorpc diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py new file mode 100644 index 00000000..10d9f9c0 --- /dev/null +++ b/src/HL/Serveur_mq.py @@ -0,0 +1,84 @@ +import zmq +context = zmq.Context() + +import time +import threading +import smbus +import logging as log + +#on démarre les log +log.basicConfig(level=log.INFO, format=Format) + +bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 + +# I2C address of the slave +SLAVE_ADDRESS = 0x08 + +length_i2c_received = 3 #le nombre de donnée récupéré par l'i2c + +# on recoit les inoformations +received = context.socket(zmq.REP) +received.connect("tcp://0.0.0.0:5555") +# on envoie les informations +send = context.socket(zmq.PUB) +send.connect("tcp://0.0.0.0:5556") + +vitesse_d = 0 +vitesse_r = 0 +direction = 0 + +voltage_lipo = 0 +voltage_nimh = 0 + + +def i2c_loop(): + """Envoie vitesse/direction régulièrement au microcontroleur.""" + global vitesse_d, direction + + while True: + try : + data = struct.pack('= length: + float_values = struct.unpack('f' * num_floats, bytes(data[:length])) + list_valeur = list(float_values) + + # on enregistre les valeur + voltage_lipo = list_valeur[0] + voltage_nimh = list_valeur[1] + vitesse_r = list_valeur[2] + + else: + pass + + +def msg_received(): + global vitesse_d, direction + while True : + req = sock.recv_json() + + if req["cmd"] == "set_speed": + vitesse_d = rec["value"] + elif req["cmd"] == "set_direction": + direction = rec["value"] + else: + sock.send_json({"error": "unknown"}) + + +threading.Thread(target=i2c_loop, daemon=True).start() +threading.Thread(target=i2c_received, daemon=True).start() + +msg_received() + From 27d9f4d4cf12eef3ae7b3061e3df9a765f54b232 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 01:34:50 +0100 Subject: [PATCH 021/107] fix: fix dans serveur_mq et test_serveur --- src/HL/Serveur_mq.py | 4 ++-- src/HL/test_serveur.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 10d9f9c0..27137ab2 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -67,14 +67,14 @@ def i2c_received(): def msg_received(): global vitesse_d, direction while True : - req = sock.recv_json() + req = received.recv_json() if req["cmd"] == "set_speed": vitesse_d = rec["value"] elif req["cmd"] == "set_direction": direction = rec["value"] else: - sock.send_json({"error": "unknown"}) + received.send_json({"error": "unknown"}) threading.Thread(target=i2c_loop, daemon=True).start() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 4547d486..35f95535 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -1,3 +1,4 @@ +""" import zerorpc import time @@ -14,4 +15,24 @@ received = c.read_data(3) # Adjust length as needed print("Received from slave:", received[0], received[1], received[2] ) + # Request data from the slave""" + +import zmq + +context = zmq.Context() +socket = context.socket(zmq.REQ) +socket.connect("tcp://127.0.0.1:5555") + + +def envoie_donnee(vitesse,rotation): + socket.send_json({"cmd": "set_speed", "value": vitesse}) + socket.send_json({"cmd": "set_direction", "value": rotation}) + +if __name__ == "__main__": + while(True): + vitesse= float(input("vitesse en millimetre par seconde:")) + rotation= float(input("rotation en degré:")) + c.write_vitesse_direction(vitesse,rotation) + time.sleep(0.1) # Wait for the slave to process the data+ù + # Request data from the slave \ No newline at end of file From 6ee55a03fc460ab17672c1a07826a279c4f7c107 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 02:10:40 +0100 Subject: [PATCH 022/107] fix --- src/HL/Serveur_mq.py | 21 +++++++++++---------- src/HL/test_serveur.py | 4 +++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 27137ab2..46c7e0f3 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -5,7 +5,6 @@ import threading import smbus import logging as log - #on démarre les log log.basicConfig(level=log.INFO, format=Format) @@ -18,10 +17,10 @@ # on recoit les inoformations received = context.socket(zmq.REP) -received.connect("tcp://0.0.0.0:5555") +received.bind("tcp://0.0.0.0:5555") # on envoie les informations send = context.socket(zmq.PUB) -send.connect("tcp://0.0.0.0:5556") +send.bind("tcp://0.0.0.0:5556") vitesse_d = 0 vitesse_r = 0 @@ -52,7 +51,7 @@ def i2c_received(): data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length) # Convert the byte data to a float if len(data) >= length: - float_values = struct.unpack('f' * num_floats, bytes(data[:length])) + float_values = struct.unpack('f' * length_i2c_received, bytes(data[:length])) list_valeur = list(float_values) # on enregistre les valeur @@ -70,15 +69,17 @@ def msg_received(): req = received.recv_json() if req["cmd"] == "set_speed": - vitesse_d = rec["value"] + vitesse_d = req["value"] + received.send_json({"status": "ok"}) elif req["cmd"] == "set_direction": - direction = rec["value"] + direction = req["value"] + received.send_json({"status": "ok"}) else: received.send_json({"error": "unknown"}) +if __name__ == "__main__": + threading.Thread(target=i2c_loop, daemon=True).start() + threading.Thread(target=i2c_received, daemon=True).start() -threading.Thread(target=i2c_loop, daemon=True).start() -threading.Thread(target=i2c_received, daemon=True).start() - -msg_received() + msg_received() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 35f95535..79a3e978 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -25,8 +25,10 @@ def envoie_donnee(vitesse,rotation): - socket.send_json({"cmd": "set_speed", "value": vitesse}) + socket.send_json({"cmd": "set_speed", "speed": vitesse}) + resp = socket.recv_json() socket.send_json({"cmd": "set_direction", "value": rotation}) + resp = socket.recv_json() if __name__ == "__main__": while(True): From 3c03eec0a10b440467c1890f6265f866770bb5c8 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 03:23:42 +0100 Subject: [PATCH 023/107] =?UTF-8?q?fix:=20=C3=A7a=20marche=20le=20serveur?= =?UTF-8?q?=5Fmq=20et=20le=20test=5Fserveur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 12 ++++++++++-- src/HL/test_serveur.py | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 46c7e0f3..13b5d259 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -5,8 +5,9 @@ import threading import smbus import logging as log +import struct #on démarre les log -log.basicConfig(level=log.INFO, format=Format) +log.basicConfig(level=log.INFO) bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 @@ -74,12 +75,19 @@ def msg_received(): elif req["cmd"] == "set_direction": direction = req["value"] received.send_json({"status": "ok"}) + elif req["cmd"] == "info": + received.send_json({ + "voltage_lipo": voltage_lipo, + "voltage_nimh": voltage_nimh, + "vitesse_reelle": vitesse_r, + "timestamp": time.time() + }) else: received.send_json({"error": "unknown"}) + if __name__ == "__main__": threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() - msg_received() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 79a3e978..5cb1c454 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -18,23 +18,36 @@ # Request data from the slave""" import zmq - +import time +# on envoie les données au serveur context = zmq.Context() socket = context.socket(zmq.REQ) socket.connect("tcp://127.0.0.1:5555") +# on récupère les données + +# Pour recevoir la télémétrie +sub = context.socket(zmq.SUB) +sub.connect("tcp://127.0.0.1:5556") +sub.setsockopt_string(zmq.SUBSCRIBE, "") def envoie_donnee(vitesse,rotation): - socket.send_json({"cmd": "set_speed", "speed": vitesse}) + socket.send_json({"cmd": "set_speed", "value": vitesse}) resp = socket.recv_json() socket.send_json({"cmd": "set_direction", "value": rotation}) resp = socket.recv_json() +def recoit_donnee(): + socket.send_json({"cmd": "info"}) + resp = socket.recv_json() + print(resp) if __name__ == "__main__": while(True): + vitesse= float(input("vitesse en millimetre par seconde:")) rotation= float(input("rotation en degré:")) - c.write_vitesse_direction(vitesse,rotation) + envoie_donnee(vitesse,rotation) + recoit_donnee() time.sleep(0.1) # Wait for the slave to process the data+ù # Request data from the slave \ No newline at end of file From 5fff2b0d48b7883d018a30cc1e4ba07a4a29b3ae Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 03:34:20 +0100 Subject: [PATCH 024/107] =?UTF-8?q?rajout=20de=20s=C3=A9curit=C3=A9=20pour?= =?UTF-8?q?=20Serveur=5Fmq=20et=20l'envoie=20par=20i2c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 13b5d259..ad7a5525 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -30,16 +30,24 @@ voltage_lipo = 0 voltage_nimh = 0 +initial_time = time.time() +last_cmd_time = 0 + def i2c_loop(): """Envoie vitesse/direction régulièrement au microcontroleur.""" - global vitesse_d, direction + global vitesse_d, direction, last_cmd_time while True: try : - data = struct.pack(' 100): + data = struct.pack(' Date: Sat, 15 Nov 2025 03:38:01 +0100 Subject: [PATCH 025/107] fix: erreur de syntaxe --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index ad7a5525..7108bb50 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -45,7 +45,7 @@ def i2c_loop(): bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data)) time.sleep(0.05) else: # on renvoie zero si il on a pas recue de message depuis moins de 100 milisecondes - data = struct.pack(' Date: Sat, 15 Nov 2025 04:16:56 +0100 Subject: [PATCH 026/107] =?UTF-8?q?rajout=20de=20smbus=20et=20zmq=20dans?= =?UTF-8?q?=20les=20d=C3=A9pendance=20et=20code=20test=5Fserveur=20et=20Se?= =?UTF-8?q?rveur=5Fmq=20qui=20marche?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 7 +- src/HL/Serveur_mq.py | 7 +- src/HL/test_serveur.py | 2 +- uv.lock | 183 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 182 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bba5e7f4..f374fd12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,28 +38,23 @@ rpi = [ # Note: picamera2 causes UV to auto-include rpi extras even when not requested # This is likely a UV bug. Add back when needed: # "picamera2>=0.3.0", - # AI Inference "onnxruntime>=1.8.0", - # Raspberry Pi specific hardware control "rpi-hardware-pwm>=0.1.0", "RPi.GPIO>=0.7.1", "gpiozero>=1.6.0", - # I2C and SPI communication (Linux specific) "smbus>=1.1.post2", "spidev>=3.5", - # OLED display support "luma.oled>=3.8.0", "luma.core>=2.3.0", "Adafruit-SSD1306>=1.6.0", - # Time-of-Flight sensor support "adafruit-circuitpython-vl53l0x>=3.6.0", "adafruit-blinka>=8.0.0", - # PS4 controller support "pyPS4Controller>=1.2.0", + "zmq>=0.0.0", ] diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 7108bb50..2eb24ab6 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -19,9 +19,6 @@ # on recoit les inoformations received = context.socket(zmq.REP) received.bind("tcp://0.0.0.0:5555") -# on envoie les informations -send = context.socket(zmq.PUB) -send.bind("tcp://0.0.0.0:5556") vitesse_d = 0 vitesse_r = 0 @@ -45,7 +42,9 @@ def i2c_loop(): bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data)) time.sleep(0.05) else: # on renvoie zero si il on a pas recue de message depuis moins de 100 milisecondes - data = struct.pack(' Date: Sat, 15 Nov 2025 05:40:06 +0100 Subject: [PATCH 027/107] test de rajoue d'information dans Serveur_mq --- scripts/bluetooth_auto/bluethootconnect.sh | 2 +- src/HL/Serveur_mq.py | 125 +++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/scripts/bluetooth_auto/bluethootconnect.sh b/scripts/bluetooth_auto/bluethootconnect.sh index b3ac0317..5b774d1f 100755 --- a/scripts/bluetooth_auto/bluethootconnect.sh +++ b/scripts/bluetooth_auto/bluethootconnect.sh @@ -31,4 +31,4 @@ while read -r line; do bluetoothctl connect "$mac" echo -done < ./bluethoot_mac.txt +done < ./scripts/bluetooth_auto/bluethoot_mac.txt diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 2eb24ab6..c4b4cad5 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -6,6 +6,18 @@ import smbus import logging as log import struct + +from luma.core.interface.serial import i2c +from luma.core.render import canvas +from luma.oled.device import ssd1306 +from PIL import Image, ImageDraw, ImageFont +from gpiozero import LED, Button, Buzzer +import textwrap + +from get_ip import get_ip, check_ssh_connections +import subprocess +serial = i2c(port=1, address=0x3C) +device = ssd1306(serial) #on démarre les log log.basicConfig(level=log.INFO) @@ -16,6 +28,14 @@ length_i2c_received = 3 #le nombre de donnée récupéré par l'i2c +bp_next = Button("GPIO5", bounce_time=0.1) +bp_entre = Button("GPIO6", bounce_time=0.1) +led1 = LED("GPIO17") +led2 = LED("GPIO27") +buzzer = Buzzer("GPIO26") +TEXT_HEIGHT = 11 +TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff + # on recoit les inoformations received = context.socket(zmq.REP) received.bind("tcp://0.0.0.0:5555") @@ -30,7 +50,112 @@ initial_time = time.time() last_cmd_time = 0 +ip = get_ip + +programme = { + 1: { + "name" : "Auto Driving", + "type" : "python", + "path" : "", + "info" : "Ia for CoVaPSY" + }, + 2: { + "name" : "Manual Driving With PS4 Controller", + "path" : "./scripts/commande_PS4.py", + "info" : "Commande_PS4 from bluetooth" + }, + 3: { + "name" : "Connect PS4 Controller", + "type" : "bash", + "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", + "info" : "Autoconnect Controller" + } +} + +Screen = 0 +State = 0 +#----------------------------------------------------------------------------------------------------- +# fonction utile +#----------------------------------------------------------------------------------------------------- +def make_voltage_im(): + try: #Will fail if arduino is rest ex: temporary power loss when plugu=ing in usb + received = [voltage_lipo , voltage_nimh] # Adjust length as needed + except OSError: + received = [0.0, 0.0] + print("I2C bus error") + + # filter out values below 6V and round to 2 decimal places + received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] + text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" + im = Image.new("1", (128, TEXT_HEIGHT), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + draw.text((3, 0), text, fill="white", font=font) + return im + +def display_combined_im(text): + im = Image.new("1", (128, 64), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + + # Wrap the text to fit within the width of the display + wrapped_text = textwrap.fill(text, width=20) # Adjust width as needed + draw.text((3, 0), wrapped_text, fill="white", font=font) + + voltage_im = make_voltage_im() + im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) + + with canvas(device) as draw: + draw.bitmap((0, 0), im, fill="white") + + +def Idle(): #Enable chossing between states + global Screen + global State + if Screen==0 and check_ssh_connections(): + led1.on() + Screen=1 + if not check_ssh_connections(): + led1.off() + match Screen: #Display on OLED + case 0: #IP and ssh status + ip=get_ip() + text = "Ready to SSH\nIP:"+ip + case 1: #AutoDriving mode + text = "Auto Driving" + case 2: #Manual Driving mode + text = "Manual Driving With PS4 Controller" + #PS4 controller status + case 3: #Kill all processus + text = "Kill all the process" + + if (Screen == 0): + ip=get_ip() + text = "Ready to SSH\nIP:"+ip + elif (Screen <= len(programme)): + text = programme[Screen] + + if (State==Screen): + text+=": (en cours)" + + display_combined_im(text) + + + if bp_next.is_pressed: + bp_next.wait_for_release() + Screen+=1 + if Screen>len(programme): + Screen=0 + if bp_entre.is_pressed: + bp_entre.wait_for_release() + State=Screen + if (Screen == 3): #pour teste + subprocess.run("./bluethootconnect.sh", shell=True, check=True) + +#--------------------------------------------------------------------------------------------------- +# fonction pour la communication +#--------------------------------------------------------------------------------------------------- def i2c_loop(): """Envoie vitesse/direction régulièrement au microcontroleur.""" global vitesse_d, direction, last_cmd_time From 1762638e86f797f9e31174e49b4a3fe56c4b6b9c Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 05:42:48 +0100 Subject: [PATCH 028/107] rajout de l'idle pour test --- src/HL/Serveur_mq.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index c4b4cad5..e0ab23a5 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -225,5 +225,7 @@ def msg_received(): if __name__ == "__main__": threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() - msg_received() - + threading.Thread(target=msg_received, daemon=True).start() + + while True: + Idle() From cdbcf4838da0428009abc83a536b48981a4ed503 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sat, 15 Nov 2025 05:47:39 +0100 Subject: [PATCH 029/107] fix --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index e0ab23a5..74564913 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -131,7 +131,7 @@ def Idle(): #Enable chossing between states if (Screen == 0): ip=get_ip() - text = "Ready to SSH\nIP:"+ip + text = "Ready to SSH\nIP:"+ip elif (Screen <= len(programme)): text = programme[Screen] From 79550b36a61cc45ec5a0eee33390b27c8eb2ec05 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sun, 16 Nov 2025 22:01:30 +0100 Subject: [PATCH 030/107] fix : changement dans Serveur_mq et creation d'un main dans Serveur_mq --- pyproject.toml | 4 ++ src/HL/Serveur_mq.py | 100 ++++++++++++++++++++++++++--------------- src/HL/test_serveur.py | 7 --- uv.lock | 10 +++++ 4 files changed, 77 insertions(+), 44 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f374fd12..e8680f8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,10 @@ authors = [ ] dependencies = [ + "luma-core>=2.5.1", + "luma-oled>=3.14.0", + "smbus>=1.1.post2", + "zmq>=0.0.0", ] [project.optional-dependencies] diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 74564913..f7946436 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -50,25 +50,40 @@ initial_time = time.time() last_cmd_time = 0 -ip = get_ip +ip = get_ip() + +process_output = "" programme = { + 0: { + "name" : "Ssh to :\n" + ip, + "type" : "", + "path" : "", + "info" : "" + }, 1: { "name" : "Auto Driving", "type" : "python", "path" : "", - "info" : "Ia for CoVaPSY" + "info" : "" }, 2: { - "name" : "Manual Driving With PS4 Controller", + "name" : "PS4 Controller", + "type" : "python", "path" : "./scripts/commande_PS4.py", - "info" : "Commande_PS4 from bluetooth" + "info" : "" }, 3: { - "name" : "Connect PS4 Controller", + "name" : "Connect Controller", "type" : "bash", "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", - "info" : "Autoconnect Controller" + "info" : "" + }, + 4: { + "name" : "Kill all", + "type" : "", + "path" : "", + "info" : "" } } @@ -78,12 +93,8 @@ # fonction utile #----------------------------------------------------------------------------------------------------- def make_voltage_im(): - try: #Will fail if arduino is rest ex: temporary power loss when plugu=ing in usb - received = [voltage_lipo , voltage_nimh] # Adjust length as needed - except OSError: - received = [0.0, 0.0] - print("I2C bus error") - + global voltage_lipo, voltage_nimh + received = [voltage_lipo , voltage_nimh] # Adjust length as needed # filter out values below 6V and round to 2 decimal places received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" @@ -117,40 +128,22 @@ def Idle(): #Enable chossing between states Screen=1 if not check_ssh_connections(): led1.off() - match Screen: #Display on OLED - case 0: #IP and ssh status - ip=get_ip() - text = "Ready to SSH\nIP:"+ip - case 1: #AutoDriving mode - text = "Auto Driving" - case 2: #Manual Driving mode - text = "Manual Driving With PS4 Controller" - #PS4 controller status - case 3: #Kill all processus - text = "Kill all the process" - if (Screen == 0): - ip=get_ip() - text = "Ready to SSH\nIP:"+ip - elif (Screen <= len(programme)): - text = programme[Screen] - - if (State==Screen): - text+=": (en cours)" + if (Screen <= len(programme)): + text = programme[Screen]["name"] + "\n" + process_output + print(Screen) display_combined_im(text) - if bp_next.is_pressed: bp_next.wait_for_release() Screen+=1 - if Screen>len(programme): + if Screen<=len(programme): Screen=0 if bp_entre.is_pressed: bp_entre.wait_for_release() State=Screen - if (Screen == 3): #pour teste - subprocess.run("./bluethootconnect.sh", shell=True, check=True) + start_process(Screen) #--------------------------------------------------------------------------------------------------- @@ -191,9 +184,8 @@ def i2c_received(): voltage_lipo = list_valeur[0] voltage_nimh = list_valeur[1] vitesse_r = list_valeur[2] + time.sleep(0.1) - else: - pass def msg_received(): @@ -222,6 +214,40 @@ def msg_received(): received.send_json({"error": "unknown"}) +#--------------------------------------------------------------------------------------------------- +# Processus +#--------------------------------------------------------------------------------------------------- +def stream_process_output(proc): + global process_output + process_output = "" # reset + for line in proc.stdout: + process_output = line.decode().strip() + +def start_process(num_programme): + global process, programme, process_output + try : + process.kill() + except : + pass + + programme_actuel = programme[num_programme] + if programme_actuel["type"] == "bash": + process = subprocess.Popen( + programme_actuel["path"], + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + elif programme_actuel["type"] == "python": + process = subprocess.Popen(["uv run",programme_actuel["path"]]) + + + process_output = "" + threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() +#--------------------------------------------------------------------------------------------------- +# main +#--------------------------------------------------------------------------------------------------- + if __name__ == "__main__": threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 86b4e0b5..27b51870 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -24,13 +24,6 @@ socket = context.socket(zmq.REQ) socket.connect("tcp://192.168.1.10:5555") -# on récupère les données - -# Pour recevoir la télémétrie -sub = context.socket(zmq.SUB) -sub.connect("tcp://127.0.0.1:5556") -sub.setsockopt_string(zmq.SUBSCRIBE, "") - def envoie_donnee(vitesse,rotation): socket.send_json({"cmd": "set_speed", "value": vitesse}) resp = socket.recv_json() diff --git a/uv.lock b/uv.lock index 2c10d6d5..51af874d 100644 --- a/uv.lock +++ b/uv.lock @@ -141,6 +141,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/fc/de/0a176512f6fab96eb name = "autotech" version = "0.1.0" source = { virtual = "." } +dependencies = [ + { name = "luma-core" }, + { name = "luma-oled" }, + { name = "smbus" }, + { name = "zmq" }, +] [package.optional-dependencies] docs = [ @@ -180,7 +186,9 @@ requires-dist = [ { name = "adafruit-circuitpython-vl53l0x", marker = "extra == 'rpi'", specifier = ">=3.6.0" }, { name = "adafruit-ssd1306", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, { name = "gpiozero", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, + { name = "luma-core", specifier = ">=2.5.1" }, { name = "luma-core", marker = "extra == 'rpi'", specifier = ">=2.3.0" }, + { name = "luma-oled", specifier = ">=3.14.0" }, { name = "luma-oled", marker = "extra == 'rpi'", specifier = ">=3.8.0" }, { name = "matplotlib", marker = "extra == 'simu'", specifier = ">=3.4.0" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.4.0" }, @@ -194,10 +202,12 @@ requires-dist = [ { name = "pyps4controller", marker = "extra == 'rpi'", specifier = ">=1.2.0" }, { name = "rpi-gpio", marker = "extra == 'rpi'", specifier = ">=0.7.1" }, { name = "rpi-hardware-pwm", marker = "extra == 'rpi'", specifier = ">=0.1.0" }, + { name = "smbus", specifier = ">=1.1.post2" }, { name = "smbus", marker = "extra == 'rpi'", specifier = ">=1.1.post2" }, { name = "spidev", marker = "extra == 'rpi'", specifier = ">=3.5" }, { name = "stable-baselines3", marker = "extra == 'simu'", specifier = ">=1.6.0" }, { name = "torch", marker = "extra == 'simu'", specifier = ">=1.9.0" }, + { name = "zmq", specifier = ">=0.0.0" }, { name = "zmq", marker = "extra == 'rpi'", specifier = ">=0.0.0" }, ] provides-extras = ["docs", "simu", "rpi"] From f4efd9e4054e60b2d14556664d28a09b40e80655 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sun, 16 Nov 2025 22:15:33 +0100 Subject: [PATCH 031/107] feat : its working (i thnils) --- scripts/commande_PS4.py | 25 ++++++++++++------------- src/HL/Serveur_mq.py | 5 +++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 6ecd7e69..dfdda506 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -5,22 +5,21 @@ #Pour le protocole I2C de communication entre la rasberie Pi et l'arduino import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module import numpy as np -import struct ################################################### #Intialisation du protocole I2C ################################################## - -# Create an SMBus instance -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 - -# I2C address of the slave -SLAVE_ADDRESS = 0x08 - -def write_vitesse_direction(vitesse,direction): - # Convert string to list of ASCII values - data = struct.pack(' Date: Mon, 17 Nov 2025 20:38:17 +0100 Subject: [PATCH 032/107] feat : commit (rajout de test pour le chunk de idiams --- src/HL/Serveur_mq.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 23ee6753..e03f555a 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -220,9 +220,10 @@ def stream_process_output(proc): global process_output for line in proc.stdout: process_output = line.decode().strip() - lines = stdout.split("\n") - size = 10 + lines = proc.stdout.split("\n") + size = 3 chunks = [l[i * size : (i+1) * size] for l in lines for i in range(len(l) // size + 1)] + print(chunks) def start_process(num_programme): global process, programme, process_output From 8a55a2be7e5b8f2da6e856cd819d4ac9149bb78f Mon Sep 17 00:00:00 2001 From: cbampeta Date: Mon, 17 Nov 2025 21:11:40 +0100 Subject: [PATCH 033/107] fix : changement dans commande_PS4 pour marcher avec zmq --- scripts/commande_PS4.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 8146fb17..06feece7 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -2,24 +2,22 @@ import time from threading import Thread -#Pour le protocole I2C de communication entre la rasberie Pi et l'arduino -import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module -import numpy as np - ################################################### -#Intialisation du protocole I2C +#Intialisation du protocole zmq ################################################## import zmq # on envoie les données au serveur context = zmq.Context() socket = context.socket(zmq.REQ) -socket.connect("tcp://192.168.1.10:5555") +socket.connect("tcp://127.0.0.1:5555") -def envoie_donnee(vitesse,rotation): - socket.send_json({"cmd": "set_speed", "value": vitesse}) - resp = socket.recv_json() - socket.send_json({"cmd": "set_direction", "value": rotation}) - resp = socket.recv_json() +def envoie_donnee(): + while(True): + socket.send_json({"cmd": "set_speed", "value": vitesse_m}) + resp = socket.recv_json() + socket.send_json({"cmd": "set_direction", "value": direction_d}) + resp = socket.recv_json() + time.sleep(0.02) ################################################### #Intialisation des moteurs @@ -111,12 +109,6 @@ def on_L2_press(self, value): def on_L2_release(self): #arrete la voiture lorsque L2 est arrété d'étre préssé. set_vitesse_m_ms(0) -#envoie de la direction et de l'angle toute les millisecondes -def envoie_direction_degre(): - while True : - write_vitesse_direction(int(vitesse_m), int(direction_d)) - time.sleep(0.001) - # boucle principal controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False) From 746b2c668a67a9544bb974a814268b07f01e548e Mon Sep 17 00:00:00 2001 From: cbampeta Date: Mon, 17 Nov 2025 22:49:48 +0100 Subject: [PATCH 034/107] feat: on peu maintenant lancer commande ps4 depuis la voiture avec les boutons --- pyproject.toml | 2 ++ scripts/commande_PS4.py | 1 + src/HL/Serveur_mq.py | 12 ++++++------ uv.lock | 10 ++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e8680f8e..1338949e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,8 +14,10 @@ authors = [ ] dependencies = [ + "gpiozero>=2.0.1", "luma-core>=2.5.1", "luma-oled>=3.14.0", + "netifaces>=0.11.0", "smbus>=1.1.post2", "zmq>=0.0.0", ] diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 06feece7..11a807d0 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -12,6 +12,7 @@ socket.connect("tcp://127.0.0.1:5555") def envoie_donnee(): + global vitesse_m , direction_d while(True): socket.send_json({"cmd": "set_speed", "value": vitesse_m}) resp = socket.recv_json() diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index e03f555a..ccbe3abe 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -48,7 +48,7 @@ voltage_nimh = 0 initial_time = time.time() -last_cmd_time = 0 +last_cmd_time = time.time() ip = get_ip() @@ -137,7 +137,7 @@ def Idle(): #Enable chossing between states if bp_next.is_pressed: bp_next.wait_for_release() Screen+=1 - if Screen<=len(programme): + if Screen>=len(programme): Screen=0 if bp_entre.is_pressed: bp_entre.wait_for_release() @@ -153,12 +153,12 @@ def i2c_loop(): global vitesse_d, direction, last_cmd_time while True: - try : - if (time.time()- last_cmd_time > 100): + try : + if (time.time()- last_cmd_time < 0.2): data = struct.pack(' Date: Mon, 17 Nov 2025 23:53:38 +0100 Subject: [PATCH 035/107] =?UTF-8?q?changemnet=20et=20rajout=20d'un=20afffi?= =?UTF-8?q?chage=20de=20running=20et=20de=20capacinbilit=C3=A9=20de=20kill?= =?UTF-8?q?=20les=20programme=20(mais=20tout=20les=20programme)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index ccbe3abe..6af63031 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -6,6 +6,8 @@ import smbus import logging as log import struct +import os, signal + from luma.core.interface.serial import i2c from luma.core.render import canvas @@ -54,12 +56,13 @@ process_output = "" +last_programme = 0 programme = { 0: { "name" : "Ssh to :\n" + ip, "type" : "", "path" : "", - "info" : "" + "info" : "no" }, 1: { "name" : "Auto Driving", @@ -77,7 +80,7 @@ "name" : "Connect Controller", "type" : "bash", "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", - "info" : "" + "info" : "no" }, 4: { "name" : "Kill all", @@ -130,7 +133,7 @@ def Idle(): #Enable chossing between states led1.off() if (Screen <= len(programme)): - text = programme[Screen]["name"] + "\n" + process_output + text = programme[Screen]["name"] + "\n" + programme[Screen]["info"] + "\n" + process_output display_combined_im(text) @@ -157,13 +160,13 @@ def i2c_loop(): if (time.time()- last_cmd_time < 0.2): data = struct.pack(' Date: Mon, 17 Nov 2025 23:56:10 +0100 Subject: [PATCH 036/107] feat: suppression des prints incessant --- scripts/commande_PS4.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 11a807d0..3676c8b5 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -45,12 +45,12 @@ def map_range(x, in_min,in_max, out_min, out_max): def set_direction_degre(angle_degre) : global direction_d direction_d = angle_degre - print("angle_degré: ",direction_d,"vitesse: ",vitesse_m) + #print("angle_degré: ",direction_d,"vitesse: ",vitesse_m) def set_vitesse_m_ms(vitesse_m_ms): global vitesse_m vitesse_m = vitesse_m_ms - print("angle_degré: ",direction_d,"vitesse: ",vitesse_m) + #print("angle_degré: ",direction_d,"vitesse: ",vitesse_m) def recule(): #actuellement ne sert a rien car on peux juste envoyer une vitesse négative global vitesse_m @@ -94,13 +94,13 @@ def on_L3_right(self,value): set_direction_degre(dir) def on_L3_left(self,value): - print("x_r :", value, "degré : ",map_range(value,-32767, 0, -angle_degre_max, 0 )) + #print("x_r :", value, "degré : ",map_range(value,-32767, 0, -angle_degre_max, 0 )) dir = map_range(value,-32767, 0, -angle_degre_max, 0 ) set_direction_degre(dir) def on_L2_press(self, value): - print("x_r :", value, "degré : ",map_range(value,-32767, 32767, 60, 120)) + #print("x_r :", value, "degré : ",map_range(value,-32767, 32767, 60, 120)) vit = map_range(value,-32252,32767,0,vitesse_min_m_s_soft*1000) if (vit > 0): set_vitesse_m_ms(0) From ffed0fe4bf789add6672ed82b43d21b1d67f0b08 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 00:41:02 +0100 Subject: [PATCH 037/107] feat : cela marche --- scripts/commande_PS4.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 3676c8b5..5499b019 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -28,12 +28,27 @@ def envoie_donnee(): vitesse_m = 0 # vitesse initiale en métre par milliseconde #paramètres de la fonction vitesse_m_s, à étalonner -vitesse_max_m_s_hard = 8 #vitesse que peut atteindre la voiture en métre vitesse_max_m_s_soft = 2 #vitesse maximale que l'on souhaite atteindre en métre par seconde vitesse_min_m_s_soft = -2 #vitesse arriere que l'on souhaite atteindre en métre angle_degre_max = +18 #vers la gauche +MAX_LEFT = -32767 + 3000 # deadzone 3000 +alpha = 0.3 +filtered = 0 + +def stable_direction(value): + global filtered + + # Deadzone + if value < MAX_LEFT: + target = -angle_degre_max + else: + target = map_range(value, -32767, 0, -angle_degre_max, 0) + + # Low-pass filtering + filtered = filtered * (1 - alpha) + target * alpha + return filtered # fonction naturel map de arduino pour plus de lisibilité @@ -95,7 +110,7 @@ def on_L3_right(self,value): def on_L3_left(self,value): #print("x_r :", value, "degré : ",map_range(value,-32767, 0, -angle_degre_max, 0 )) - dir = map_range(value,-32767, 0, -angle_degre_max, 0 ) + dir = stable_direction(value) set_direction_degre(dir) From a594278f0c23b723b169ccb49ba2e39928ee2c68 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 10:31:58 +0100 Subject: [PATCH 038/107] =?UTF-8?q?feat:=20rajout=20de=20la=20possibilit?= =?UTF-8?q?=C3=A9=20de=20prendre=20le=20control=20de=20la=20voiture=20a=20?= =?UTF-8?q?distance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 52 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 6af63031..d2df15f7 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -39,8 +39,13 @@ TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff # on recoit les inoformations -received = context.socket(zmq.REP) -received.bind("tcp://0.0.0.0:5555") +private = context.socket(zmq.REP) +private.bind("tcp://127.0.0.1:5555") + +public = context.socket(zmq.REP) +public.bind("tcp://192.168.0.10:5556") + +remote_control = False # on initialise le remote control à False vitesse_d = 0 vitesse_r = 0 @@ -83,6 +88,12 @@ "info" : "no" }, 4: { + "name" : "Remote control", + "type" : "function", + "path" : switch_remote_control(), + "info" : "" + }, + 5: { "name" : "Kill all", "type" : "", "path" : "", @@ -190,30 +201,32 @@ def i2c_received(): -def msg_received(): - global vitesse_d, direction, last_cmd_time - while True : - req = received.recv_json() +def msg_received(socket, is_private): + """ on regarde si il s'agit de lappelle pour le control interne + (is_private) ou si on veux prendre le controle depuis le pc.""" + global vitesse_d, direction, last_cmd_time, remote_control + while is_private or remote_control: + req = socket.recv_json() if req["cmd"] == "set_speed": vitesse_d = req["value"] - received.send_json({"status": "ok"}) + socket.send_json({"status": "ok"}) last_cmd_time = time.time() elif req["cmd"] == "set_direction": direction = req["value"] - received.send_json({"status": "ok"}) + socket.send_json({"status": "ok"}) last_cmd_time = time.time() elif req["cmd"] == "info": - received.send_json({ + socket.send_json({ "voltage_lipo": voltage_lipo, "voltage_nimh": voltage_nimh, "vitesse_reelle": vitesse_r, "timestamp": time.time() - initial_time }) else: - received.send_json({"error": "unknown"}) + socket.send_json({"error": "unknown"}) #--------------------------------------------------------------------------------------------------- @@ -257,10 +270,25 @@ def start_process(num_programme): stderr=subprocess.STDOUT, preexec_fn=os.setsid ) - + elif programme_actuel["type"] == "function": + programme_actuel["path"] process_output = "" threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + + +#--------------------------------------------------------------------------------------------------- +# car function +#--------------------------------------------------------------------------------------------------- + +def switch_remote_control(): + global remote_control + if remote_control: + remote_control = False + else: + remote_control = True + threading.Thread(target=msg_received, args=(public,False,), daemon=True).start() + #--------------------------------------------------------------------------------------------------- # main #--------------------------------------------------------------------------------------------------- @@ -268,7 +296,7 @@ def start_process(num_programme): if __name__ == "__main__": threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() - threading.Thread(target=msg_received, daemon=True).start() + threading.Thread(target=msg_received, args=(private,True,), daemon=True).start() while True: Idle() From 9bfa0021ac5336735ab30c00eee78d6079f22d16 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 16:13:07 +0100 Subject: [PATCH 039/107] =?UTF-8?q?fix=20:=20on=20essaye=20de=20connecter?= =?UTF-8?q?=20le=20reste=20=C3=A0=20la=20pi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/remote_control_controller.py | 106 +++++++++++++++++++++++++++ src/HL/Serveur_mq.py | 17 +++-- 2 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 scripts/remote_control_controller.py diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py new file mode 100644 index 00000000..1d9eaf4e --- /dev/null +++ b/scripts/remote_control_controller.py @@ -0,0 +1,106 @@ +import pygame +import zmq +import time +from threading import Thread + +################################################### +# Init ZMQ +################################################### +context = zmq.Context() +socket = context.socket(zmq.REQ) +socket.connect("tcp://192.168.1.10:5555") + +def envoie_donnee(): + global vitesse_m, direction_d + while True: + socket.send_json({"cmd": "set_speed", "value": vitesse_m}) + socket.recv_json() + + socket.send_json({"cmd": "set_direction", "value": direction_d}) + socket.recv_json() + + time.sleep(0.02) + +################################################### +# Paramètres véhicule +################################################### +direction_d = 0 +vitesse_m = 0 + +vitesse_max_m_s_soft = 2 +vitesse_min_m_s_soft = -2 +angle_degre_max = 18 + +def map_range(x, in_min, in_max, out_min, out_max): + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min + +def set_direction_degre(angle_degre): + global direction_d + direction_d = angle_degre + print("direction:", direction_d, "vitesse:", vitesse_m) + +def set_vitesse_m_ms(vit): + global vitesse_m + vitesse_m = vit + print("direction:", direction_d, "vitesse:", vitesse_m) + +################################################### +# Init pygame + manette +################################################### +pygame.init() +pygame.joystick.init() + +if pygame.joystick.get_count() == 0: + print("Aucune manette détectée") + exit(1) + +joy = pygame.joystick.Joystick(0) +joy.init() +print("Manette détectée:", joy.get_name()) + +################################################### +# Boucle principale +################################################### +Thread(target=envoie_donnee, daemon=True).start() + +try: + while True: + pygame.event.pump() + + # Axes : + # Pour Xbox/PS4 USB : + # L2 = axis 2 (souvent 0..1) + # R2 = axis 5 (souvent 0..1) + # Stick gauche horizontal = axis 0 (-1..1) + + axis_lx = joy.get_axis(0) # Gauche droite + axis_l2 = joy.get_axis(2) # Accélération inverse + axis_r2 = joy.get_axis(5) # Accélération + + + # Direction + direction = map_range(axis_lx, -1, 1, -angle_degre_max, angle_degre_max) + set_direction_degre(direction) + + # Accélération + accel = (axis_r2 + 1)/2 + brake = (axis_l2 + 1)/2 + + # Certaines manettes vont de -1..1, d'autres 0..1 + + # Avant + if accel > 0.05: + vit = accel * vitesse_max_m_s_soft * 1000 + set_vitesse_m_ms(vit) + + # Arrière + elif brake > 0.05: + vit = brake * vitesse_min_m_s_soft * 1000 + set_vitesse_m_ms(vit) + else : + set_vitesse_m_ms(0) + time.sleep(0.01) + +except KeyboardInterrupt: + print("Fin du programme.") + pygame.quit() diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index d2df15f7..511bf96b 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -43,7 +43,7 @@ private.bind("tcp://127.0.0.1:5555") public = context.socket(zmq.REP) -public.bind("tcp://192.168.0.10:5556") +public.bind("tcp://192.168.1.10:5556") remote_control = False # on initialise le remote control à False @@ -59,9 +59,9 @@ ip = get_ip() - process_output = "" last_programme = 0 +process = None programme = { 0: { "name" : "Ssh to :\n" + ip, @@ -90,7 +90,7 @@ 4: { "name" : "Remote control", "type" : "function", - "path" : switch_remote_control(), + "path" : switch_remote_control, "info" : "" }, 5: { @@ -250,10 +250,11 @@ def start_process(num_programme): programme[num_programme]["info"] = "(running)" last_programme = num_programme - try : - os.killpg(os.getpgid(process.pid), signal.SIGTERM) - except : - pass + if process is not None: + try: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + except: + pass programme_actuel = programme[num_programme] if programme_actuel["type"] == "bash": @@ -271,7 +272,7 @@ def start_process(num_programme): preexec_fn=os.setsid ) elif programme_actuel["type"] == "function": - programme_actuel["path"] + programme_actuel["path"]() process_output = "" threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() From 06b8ff1832abb6c1e3be2416ed9418f2cdd6d67a Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 17:49:35 +0100 Subject: [PATCH 040/107] feat : passage en sub/pub pour soucis de vitesse --- scripts/remote_control_controller.py | 14 ++----- src/HL/Serveur_mq.py | 55 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py index 1d9eaf4e..0ffdd4d5 100644 --- a/scripts/remote_control_controller.py +++ b/scripts/remote_control_controller.py @@ -7,19 +7,15 @@ # Init ZMQ ################################################### context = zmq.Context() -socket = context.socket(zmq.REQ) -socket.connect("tcp://192.168.1.10:5555") +socket = context.socket(zmq.PUB) +socket.connect("tcp://192.168.1.10:5556") def envoie_donnee(): global vitesse_m, direction_d while True: socket.send_json({"cmd": "set_speed", "value": vitesse_m}) - socket.recv_json() - socket.send_json({"cmd": "set_direction", "value": direction_d}) - socket.recv_json() - - time.sleep(0.02) + time.sleep(0.01) ################################################### # Paramètres véhicule @@ -37,12 +33,11 @@ def map_range(x, in_min, in_max, out_min, out_max): def set_direction_degre(angle_degre): global direction_d direction_d = angle_degre - print("direction:", direction_d, "vitesse:", vitesse_m) + print(direction_d, vitesse_m) def set_vitesse_m_ms(vit): global vitesse_m vitesse_m = vit - print("direction:", direction_d, "vitesse:", vitesse_m) ################################################### # Init pygame + manette @@ -76,7 +71,6 @@ def set_vitesse_m_ms(vit): axis_lx = joy.get_axis(0) # Gauche droite axis_l2 = joy.get_axis(2) # Accélération inverse axis_r2 = joy.get_axis(5) # Accélération - # Direction direction = map_range(axis_lx, -1, 1, -angle_degre_max, angle_degre_max) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 511bf96b..fe3206a4 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -39,11 +39,17 @@ TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff # on recoit les inoformations -private = context.socket(zmq.REP) +private = context.socket(zmq.SUB) private.bind("tcp://127.0.0.1:5555") +private.setsockopt_string(zmq.SUBSCRIBE, "") + +public = context.socket(zmq.SUB) +public.bind("tcp://0.0.0.0:5556") +public.setsockopt_string(zmq.SUBSCRIBE, "") + +telemetry = context.socket(zmq.REQ) +telemetry.bind("tcp://127.0.0.1:5557") -public = context.socket(zmq.REP) -public.bind("tcp://192.168.1.10:5556") remote_control = False # on initialise le remote control à False @@ -90,7 +96,7 @@ 4: { "name" : "Remote control", "type" : "function", - "path" : switch_remote_control, + "path" : lambda: switch_remote_control(), "info" : "" }, 5: { @@ -205,28 +211,30 @@ def msg_received(socket, is_private): """ on regarde si il s'agit de lappelle pour le control interne (is_private) ou si on veux prendre le controle depuis le pc.""" global vitesse_d, direction, last_cmd_time, remote_control - while is_private or remote_control: + + while is_private or remote_control: req = socket.recv_json() + # info = telemetry.recv_json() if req["cmd"] == "set_speed": + print("lololol") vitesse_d = req["value"] - socket.send_json({"status": "ok"}) last_cmd_time = time.time() elif req["cmd"] == "set_direction": direction = req["value"] - socket.send_json({"status": "ok"}) last_cmd_time = time.time() - - elif req["cmd"] == "info": - socket.send_json({ + + else: + socket.send_json({"error": "unknown"}) + """ + elif info["cmd"] == "info": + telemetry.send_json({ "voltage_lipo": voltage_lipo, "voltage_nimh": voltage_nimh, "vitesse_reelle": vitesse_r, "timestamp": time.time() - initial_time - }) - else: - socket.send_json({"error": "unknown"}) + })""" #--------------------------------------------------------------------------------------------------- @@ -236,10 +244,11 @@ def stream_process_output(proc): global process_output for line in proc.stdout: process_output = line.decode().strip() + """ lines = proc.stdout.split("\n") size = 3 chunks = [l[i * size : (i+1) * size] for l in lines for i in range(len(l) // size + 1)] - print(chunks) + print(chunks)""" def start_process(num_programme): global process, programme, process_output, last_programme @@ -248,13 +257,14 @@ def start_process(num_programme): programme[last_programme]["info"] = "" if programme[num_programme]["info"] != "no": programme[num_programme]["info"] = "(running)" - + + process_output = "" last_programme = num_programme if process is not None: try: os.killpg(os.getpgid(process.pid), signal.SIGTERM) - except: - pass + except Exception as e: + print(e) programme_actuel = programme[num_programme] if programme_actuel["type"] == "bash": @@ -265,17 +275,21 @@ def start_process(num_programme): stderr=subprocess.STDOUT, preexec_fn=os.setsid ) + + threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() elif programme_actuel["type"] == "python": process = subprocess.Popen(["uv","run",programme_actuel["path"]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid ) + + threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() elif programme_actuel["type"] == "function": programme_actuel["path"]() - process_output = "" - threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + + #--------------------------------------------------------------------------------------------------- @@ -283,9 +297,10 @@ def start_process(num_programme): #--------------------------------------------------------------------------------------------------- def switch_remote_control(): - global remote_control + global remote_control, last_programme if remote_control: remote_control = False + programme[last_programme]["info"] = "" else: remote_control = True threading.Thread(target=msg_received, args=(public,False,), daemon=True).start() From 2fc28830ab1d59aa86bbbf3438b28bf6d3c55f16 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 18:00:57 +0100 Subject: [PATCH 041/107] feat : mise a jour de commande_PS4 pour marcher avec la nouvelle structure --- scripts/commande_PS4.py | 10 ++++------ src/HL/Serveur_mq.py | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 5499b019..4a6adf74 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -8,17 +8,15 @@ import zmq # on envoie les données au serveur context = zmq.Context() -socket = context.socket(zmq.REQ) +socket = context.socket(zmq.PUB) socket.connect("tcp://127.0.0.1:5555") def envoie_donnee(): - global vitesse_m , direction_d - while(True): + global vitesse_m, direction_d + while True: socket.send_json({"cmd": "set_speed", "value": vitesse_m}) - resp = socket.recv_json() socket.send_json({"cmd": "set_direction", "value": direction_d}) - resp = socket.recv_json() - time.sleep(0.02) + time.sleep(0.01) ################################################### #Intialisation des moteurs diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index fe3206a4..c842d0a1 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -217,7 +217,6 @@ def msg_received(socket, is_private): # info = telemetry.recv_json() if req["cmd"] == "set_speed": - print("lololol") vitesse_d = req["value"] last_cmd_time = time.time() From e71c658df17965bc6be78b6ff61edde9cc18b3a0 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 19:13:38 +0100 Subject: [PATCH 042/107] feat : utilisation de udp pour controller la voiture a distance --- scripts/commande_PS4.py | 18 ++++++++++-------- scripts/remote_control_controller.py | 13 ++++++------- src/HL/Serveur_mq.py | 26 +++++++++++++++++++++----- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 4a6adf74..59dbdbff 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -5,18 +5,20 @@ ################################################### #Intialisation du protocole zmq ################################################## -import zmq -# on envoie les données au serveur -context = zmq.Context() -socket = context.socket(zmq.PUB) -socket.connect("tcp://127.0.0.1:5555") +import socket +import struct +################################################### +# Init ZMQ +################################################### +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) def envoie_donnee(): global vitesse_m, direction_d while True: - socket.send_json({"cmd": "set_speed", "value": vitesse_m}) - socket.send_json({"cmd": "set_direction", "value": direction_d}) - time.sleep(0.01) + packet = struct.pack("ff", vitesse_m, direction_d) + sock.sendto(packet, ("127.0.0.1", 5556)) + time.sleep(0.05) + ################################################### #Intialisation des moteurs diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py index 0ffdd4d5..fe2234ed 100644 --- a/scripts/remote_control_controller.py +++ b/scripts/remote_control_controller.py @@ -2,20 +2,19 @@ import zmq import time from threading import Thread - +import socket +import struct ################################################### # Init ZMQ ################################################### -context = zmq.Context() -socket = context.socket(zmq.PUB) -socket.connect("tcp://192.168.1.10:5556") +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) def envoie_donnee(): global vitesse_m, direction_d while True: - socket.send_json({"cmd": "set_speed", "value": vitesse_m}) - socket.send_json({"cmd": "set_direction", "value": direction_d}) - time.sleep(0.01) + packet = struct.pack("ff", vitesse_m, direction_d) + sock.sendto(packet, ("192.168.1.10", 5556)) + time.sleep(0.05) ################################################### # Paramètres véhicule diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index c842d0a1..0f0e426e 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -15,6 +15,7 @@ from PIL import Image, ImageDraw, ImageFont from gpiozero import LED, Button, Buzzer import textwrap +import socket from get_ip import get_ip, check_ssh_connections import subprocess @@ -39,6 +40,7 @@ TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff # on recoit les inoformations +""" private = context.socket(zmq.SUB) private.bind("tcp://127.0.0.1:5555") private.setsockopt_string(zmq.SUBSCRIBE, "") @@ -46,6 +48,12 @@ public = context.socket(zmq.SUB) public.bind("tcp://0.0.0.0:5556") public.setsockopt_string(zmq.SUBSCRIBE, "") +""" +public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +public.bind(("0.0.0.0", 5556)) + +private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +private.bind(("0.0.0.0", 5555)) telemetry = context.socket(zmq.REQ) telemetry.bind("tcp://127.0.0.1:5557") @@ -104,6 +112,12 @@ "type" : "", "path" : "", "info" : "" + }, + 6: { + "name" : "reboot", + "type" : "bash", + "path" : "poweroff", + "info" : "" } } @@ -174,7 +188,8 @@ def i2c_loop(): while True: try : - if (time.time()- last_cmd_time < 0.2): + + if (time.time()- last_cmd_time < 0.5): data = struct.pack(' Date: Tue, 18 Nov 2025 19:35:54 +0100 Subject: [PATCH 043/107] fix: commande ps4 et serveur pour bien ensemble marcher --- scripts/commande_PS4.py | 2 +- src/HL/Serveur_mq.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 59dbdbff..c7ce0857 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -16,7 +16,7 @@ def envoie_donnee(): global vitesse_m, direction_d while True: packet = struct.pack("ff", vitesse_m, direction_d) - sock.sendto(packet, ("127.0.0.1", 5556)) + sock.sendto(packet, ("127.0.0.1", 5555)) time.sleep(0.05) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 0f0e426e..acb73769 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -53,7 +53,7 @@ public.bind(("0.0.0.0", 5556)) private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -private.bind(("0.0.0.0", 5555)) +private.bind(("127.0.0.1", 5555)) telemetry = context.socket(zmq.REQ) telemetry.bind("tcp://127.0.0.1:5557") From b120946525ffe4a4d1fae268b8fe335d4f94f6f4 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 19:38:56 +0100 Subject: [PATCH 044/107] fix : reimplementation de l'envoie d'info par Serveur_mq --- src/HL/Serveur_mq.py | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index acb73769..ffcd1073 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -222,7 +222,7 @@ def i2c_received(): -def msg_received(socket, is_private): +def car_controle(socket, is_private): """ on regarde si il s'agit de lappelle pour le control interne (is_private) ou si on veux prendre le controle depuis le pc.""" global vitesse_d, direction, last_cmd_time, remote_control @@ -231,26 +231,21 @@ def msg_received(socket, is_private): data, _ = socket.recvfrom(1024) vitesse_d, direction = struct.unpack("ff", data) last_cmd_time = time.time() - """ - req = socket.recv_json() - # info = telemetry.recv_json() - - if req["cmd"] == "set_speed": - vitesse_d = req["value"] - last_cmd_time = time.time() - - elif req["cmd"] == "set_direction": - direction = req["value"] - last_cmd_time = time.time() - """ """ - elif info["cmd"] == "info": + +def envoie_donnee(socket): + """ on regarde si il s'agit de lappelle pour le control interne + (is_private) ou si on veux prendre le controle depuis le pc.""" + global vitesse_d, direction, last_cmd_time, remote_control + + while is_private or remote_control: + info = telemetry.recv_json() + if info["cmd"] == "info": telemetry.send_json({ "voltage_lipo": voltage_lipo, "voltage_nimh": voltage_nimh, "vitesse_reelle": vitesse_r, "timestamp": time.time() - initial_time - })""" - + }) #--------------------------------------------------------------------------------------------------- # Processus @@ -327,7 +322,7 @@ def switch_remote_control(): if __name__ == "__main__": threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() - threading.Thread(target=msg_received, args=(private,True,), daemon=True).start() + threading.Thread(target=car_controle, args=(private,True,), daemon=True).start() while True: Idle() From f6928f9d878d46aeb3e57db12751fa0eba0a363a Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 19:40:40 +0100 Subject: [PATCH 045/107] fix: chnaghement de non dans switch_remote_control --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index ffcd1073..48bd6746 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -313,7 +313,7 @@ def switch_remote_control(): programme[last_programme]["info"] = "" else: remote_control = True - threading.Thread(target=msg_received, args=(public,False,), daemon=True).start() + threading.Thread(target=car_controle, args=(public,False,), daemon=True).start() #--------------------------------------------------------------------------------------------------- # main From e04f42a4676ff13b0c30d55b5e155c9cf393db85 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 19:55:23 +0100 Subject: [PATCH 046/107] rajout de bouton reboot --- scripts/remote_control_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py index fe2234ed..4f96c805 100644 --- a/scripts/remote_control_controller.py +++ b/scripts/remote_control_controller.py @@ -14,7 +14,7 @@ def envoie_donnee(): while True: packet = struct.pack("ff", vitesse_m, direction_d) sock.sendto(packet, ("192.168.1.10", 5556)) - time.sleep(0.05) + time.sleep(0.1) ################################################### # Paramètres véhicule From 5cdb8bea97288378e960ac06df833cb08ade2756 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 18 Nov 2025 19:55:28 +0100 Subject: [PATCH 047/107] feat :rajout de bouton reboot --- scripts/remote_control_controller.py | 2 +- src/HL/Serveur_mq.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py index 4f96c805..fe2234ed 100644 --- a/scripts/remote_control_controller.py +++ b/scripts/remote_control_controller.py @@ -14,7 +14,7 @@ def envoie_donnee(): while True: packet = struct.pack("ff", vitesse_m, direction_d) sock.sendto(packet, ("192.168.1.10", 5556)) - time.sleep(0.1) + time.sleep(0.05) ################################################### # Paramètres véhicule diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 48bd6746..72019b04 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -116,7 +116,7 @@ 6: { "name" : "reboot", "type" : "bash", - "path" : "poweroff", + "path" : "sudo reboot", "info" : "" } } @@ -189,7 +189,7 @@ def i2c_loop(): while True: try : - if (time.time()- last_cmd_time < 0.5): + if (time.time()- last_cmd_time < 1): data = struct.pack(' Date: Wed, 19 Nov 2025 16:12:50 +0100 Subject: [PATCH 048/107] fix : on a serveur_mq et remote_controle et test_serveur qui marche bien --- scripts/remote_control_controller.py | 6 +++--- src/HL/Serveur_mq.py | 17 +++++++++++------ src/HL/test_serveur.py | 11 +---------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/scripts/remote_control_controller.py b/scripts/remote_control_controller.py index fe2234ed..294105d9 100644 --- a/scripts/remote_control_controller.py +++ b/scripts/remote_control_controller.py @@ -73,7 +73,7 @@ def set_vitesse_m_ms(vit): # Direction direction = map_range(axis_lx, -1, 1, -angle_degre_max, angle_degre_max) - set_direction_degre(direction) + set_direction_degre(round(direction)) # Accélération accel = (axis_r2 + 1)/2 @@ -84,12 +84,12 @@ def set_vitesse_m_ms(vit): # Avant if accel > 0.05: vit = accel * vitesse_max_m_s_soft * 1000 - set_vitesse_m_ms(vit) + set_vitesse_m_ms(round(vit)) # Arrière elif brake > 0.05: vit = brake * vitesse_min_m_s_soft * 1000 - set_vitesse_m_ms(vit) + set_vitesse_m_ms(round(vit)) else : set_vitesse_m_ms(0) time.sleep(0.01) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 72019b04..6b6278db 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -49,13 +49,15 @@ public.bind("tcp://0.0.0.0:5556") public.setsockopt_string(zmq.SUBSCRIBE, "") """ +# on envoie en udp les commandes de la ps4 public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) public.bind(("0.0.0.0", 5556)) private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) private.bind(("127.0.0.1", 5555)) -telemetry = context.socket(zmq.REQ) +# on utilise tcp pour les infos des différents informations +telemetry = context.socket(zmq.REP) telemetry.bind("tcp://127.0.0.1:5557") @@ -190,7 +192,7 @@ def i2c_loop(): try : if (time.time()- last_cmd_time < 1): - data = struct.pack(' Date: Wed, 19 Nov 2025 16:39:17 +0100 Subject: [PATCH 049/107] =?UTF-8?q?fix=20:=20reduction=20du=20lag=20dans?= =?UTF-8?q?=20la=20direction=20en=20envoie=20(j'ai=20supprimer=20le=20time?= =?UTF-8?q?.sleep=20sa=20fait=20peur=20mais=20l'arduino=20tank=20(j'=C3=A9?= =?UTF-8?q?spere))?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 6b6278db..20de1f9e 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -194,7 +194,7 @@ def i2c_loop(): if (time.time()- last_cmd_time < 1): data = struct.pack(' Date: Wed, 19 Nov 2025 18:00:18 +0100 Subject: [PATCH 050/107] =?UTF-8?q?rajout=20de=20la=20r=C3=A9cup=C3=A9rati?= =?UTF-8?q?on=20des=20donn=C3=A9e=20du=20lidar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 + src/HL/Serveur_mq.py | 34 +++++++++++++++++++++++- src/HL/test_serveur.py | 59 ++++++++++++++++++++++++++++-------------- uv.lock | 2 ++ 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1338949e..392e2b11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "gpiozero>=2.0.1", "luma-core>=2.5.1", "luma-oled>=3.14.0", + "matplotlib[rpi]>=3.10.5", "netifaces>=0.11.0", "smbus>=1.1.post2", "zmq>=0.0.0", diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 20de1f9e..e5a9b576 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -19,6 +19,9 @@ from get_ip import get_ip, check_ssh_connections import subprocess +from Lidar import Lidar +from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET + serial = i2c(port=1, address=0x3C) device = ssd1306(serial) #on démarre les log @@ -75,6 +78,7 @@ ip = get_ip() +#donnée des process process_output = "" last_programme = 0 process = None @@ -123,6 +127,12 @@ } } +#donnée du lidar +lidar = None +rDistance = [] +xTheta = 0 + +# donnée de l'écran Screen = 0 State = 0 #----------------------------------------------------------------------------------------------------- @@ -180,7 +190,17 @@ def Idle(): #Enable chossing between states State=Screen start_process(Screen) - +def _initialize_lidar(): + """Initialize the Lidar sensor.""" + global lidar + try: + lidar = Lidar(SOCKET_ADRESS["IP"], SOCKET_ADRESS["PORT"]) + lidar.stop() + lidar.startContinuous(0, 1080) + print("Lidar initialized successfully") + except Exception as e: + print(f"Error initializing Lidar: {e}") + raise #--------------------------------------------------------------------------------------------------- # fonction pour la communication #--------------------------------------------------------------------------------------------------- @@ -251,6 +271,17 @@ def envoie_donnee(socket): else : socket.send_json({"Error" : "not understand"}) +def lidar_update_data(): + global rDistance, xTheta + _initialize_lidar() + while True: + try : + rDistance = lidar.rDistance + xTheta = lidar.xTheta + time.sleep(0.1) + except : + print("pas lidar") + time.sleep(1) #--------------------------------------------------------------------------------------------------- # Processus #--------------------------------------------------------------------------------------------------- @@ -328,6 +359,7 @@ def switch_remote_control(): threading.Thread(target=i2c_received, daemon=True).start() threading.Thread(target=car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=envoie_donnee, args=(telemetry,), daemon=True).start() + threading.Thread(target=lidar_update_data, daemon=True).start() while True: Idle() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index 2c5b91b6..67c1c088 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -1,22 +1,3 @@ -""" -import zerorpc -import time - -c = zerorpc.Client() -c.connect(f"tcp://0.0.0.0:4242") - - -if __name__ == "__main__": - while(True): - vitesse= float(input("vitesse en millimetre par seconde:")) - rotation= float(input("rotation en degré:")) - c.write_vitesse_direction(vitesse,rotation) - time.sleep(0.1) # Wait for the slave to process the data - received = c.read_data(3) # Adjust length as needed - print("Received from slave:", received[0], received[1], received[2] ) - - # Request data from the slave""" - import zmq import time # on envoie les données au serveur @@ -29,6 +10,46 @@ def recoit_donnee(): resp = socket.recv_json() print(resp) +rDistance = None +xTheta = None + +def startPlotter(self, autorange=False): + def toCartesian(xTheta, xR): + X = np.cos(xTheta) * xR + Y = np.sin(xTheta) * xR + return X,Y + + plt.show() + fig = plt.figure() + axc = plt.subplot(121) + axp = plt.subplot(122, projection='polar') + # axp.set_thetamax(deg2theta(45)) + # axp.set_thetamax(deg2theta(270 + 45)) + axp.grid(True) + log.info('Plotter started, press any key to exit') + + log.debug(f'{xTheta}, {rDistance}') + while True: + X, Y = toCartesian(xTheta, rDistance) + + axp.clear() + axc.clear() + + axp.plot(xTheta, rDistance) + + axc.plot(X, Y) + + if not autorange: + axp.set_rmax(8000) + axc.set_xlim(-5000, 5000) + axc.set_ylim(-5000, 5000) + + plt.pause(1e-17) + + if plt.waitforbuttonpress(timeout=0.02): + os._exit(0) + + if __name__ == "__main__": while(True): recoit_donnee() diff --git a/uv.lock b/uv.lock index 2a5ff67d..4f641b61 100644 --- a/uv.lock +++ b/uv.lock @@ -145,6 +145,7 @@ dependencies = [ { name = "gpiozero" }, { name = "luma-core" }, { name = "luma-oled" }, + { name = "matplotlib" }, { name = "netifaces" }, { name = "smbus" }, { name = "zmq" }, @@ -194,6 +195,7 @@ requires-dist = [ { name = "luma-oled", specifier = ">=3.14.0" }, { name = "luma-oled", marker = "extra == 'rpi'", specifier = ">=3.8.0" }, { name = "matplotlib", marker = "extra == 'simu'", specifier = ">=3.4.0" }, + { name = "matplotlib", extras = ["rpi"], specifier = ">=3.10.5" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.4.0" }, { name = "mkdocs-git-authors-plugin", marker = "extra == 'docs'", specifier = ">=0.6.0" }, { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'docs'", specifier = ">=1.1.0" }, From b5df107c31dc735c4465eff59114ed930a825ab0 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 19 Nov 2025 18:20:31 +0100 Subject: [PATCH 051/107] fix : enleve le raise si on trouve pas le lidar --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index e5a9b576..005c03fd 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -200,7 +200,7 @@ def _initialize_lidar(): print("Lidar initialized successfully") except Exception as e: print(f"Error initializing Lidar: {e}") - raise + #--------------------------------------------------------------------------------------------------- # fonction pour la communication #--------------------------------------------------------------------------------------------------- From 4b16f5026c24d85bf260b409c5337d85118024dd Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 00:40:58 +0100 Subject: [PATCH 052/107] fix : changement dans startup pour lancer Serveur_mq avec uv --- scripts/startup.sh | 5 +++-- src/HL/Serveur_mq.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/startup.sh b/scripts/startup.sh index 6571a8df..5cbcef2c 100755 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -15,5 +15,6 @@ cd /home/intech/CoVAPSy # Pull the latest changes from the repository git pull -# Run the main Python script -python /home/intech/CoVAPSy/src/HL/main.py \ No newline at end of file +/home/intech/.local/bin/uv sync +/home/intech/.local/bin/uv sync --extra rpi +/home/intech/.local/bin/uv run /home/intech/CoVAPSy/src/HL/Serveur_mq.py diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 005c03fd..8299bc4a 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -169,6 +169,7 @@ def display_combined_im(text): def Idle(): #Enable chossing between states global Screen global State + if Screen==0 and check_ssh_connections(): led1.on() Screen=1 From 0109b51d3dfdd9fdf8dd99abacca993a8f7a65be Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 00:43:08 +0100 Subject: [PATCH 053/107] fix : enlevage de l'affichage de no de info --- src/HL/Serveur_mq.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 8299bc4a..9524e41b 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -177,8 +177,11 @@ def Idle(): #Enable chossing between states led1.off() if (Screen <= len(programme)): - text = programme[Screen]["name"] + "\n" + programme[Screen]["info"] + "\n" + process_output - + if programme[Screen]["info"] != "no" : + text = programme[Screen]["name"] + "\n" + programme[Screen]["info"] + "\n" + process_output + else : + text = programme[Screen]["name"] + "\n" + process_output + display_combined_im(text) if bp_next.is_pressed: From 0a7689191bc96b2c9b9b7aef0789bb20fceafea1 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 00:52:10 +0100 Subject: [PATCH 054/107] =?UTF-8?q?fix:=20r=C3=A9solution=20de=20l'appel?= =?UTF-8?q?=20de=20uv=20directement=20dans=20startup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/startup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/startup.sh b/scripts/startup.sh index 5cbcef2c..0df29d1d 100755 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -1,7 +1,8 @@ #!/bin/bash # Specify the PATH -export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin +export PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" + # Wait until WiFi is acquired while ! ping -c 1 google.com &> /dev/null; do @@ -15,6 +16,6 @@ cd /home/intech/CoVAPSy # Pull the latest changes from the repository git pull -/home/intech/.local/bin/uv sync -/home/intech/.local/bin/uv sync --extra rpi -/home/intech/.local/bin/uv run /home/intech/CoVAPSy/src/HL/Serveur_mq.py +uv sync +uv sync --extra rpi +uv run /home/intech/CoVAPSy/src/HL/Serveur_mq.py From 01df9b428b214cedade7146d550d5e949b7e2bdc Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 01:52:31 +0100 Subject: [PATCH 055/107] feat: passage a l'utilisatinon de when_pressed --- src/HL/Serveur_mq.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 9524e41b..92eb52ec 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -181,18 +181,21 @@ def Idle(): #Enable chossing between states text = programme[Screen]["name"] + "\n" + programme[Screen]["info"] + "\n" + process_output else : text = programme[Screen]["name"] + "\n" + process_output - + display_combined_im(text) - if bp_next.is_pressed: - bp_next.wait_for_release() - Screen+=1 - if Screen>=len(programme): - Screen=0 - if bp_entre.is_pressed: - bp_entre.wait_for_release() - State=Screen - start_process(Screen) +def bouton_next(): + global Screen + Screen+=1 + if Screen>=len(programme): + Screen=0 + +def bouton_entre(num=None): + global Screen, State + if num!=None: + Screen = num + State=Screen + start_process(Screen) def _initialize_lidar(): """Initialize the Lidar sensor.""" @@ -254,9 +257,10 @@ def car_controle(socket, is_private): global vitesse_d, direction, last_cmd_time, remote_control while is_private or remote_control: - data, _ = socket.recvfrom(1024) + data, ip = socket.recvfrom(1024) vitesse_d, direction = struct.unpack("ff", data) last_cmd_time = time.time() + print(ip) def envoie_donnee(socket): """ on regarde si il s'agit de lappelle pour le control interne @@ -359,6 +363,10 @@ def switch_remote_control(): #--------------------------------------------------------------------------------------------------- if __name__ == "__main__": + + bp_next.when_pressed = bouton_next + bp_entre.when_pressed = bouton_entre + threading.Thread(target=i2c_loop, daemon=True).start() threading.Thread(target=i2c_received, daemon=True).start() threading.Thread(target=car_controle, args=(private,True,), daemon=True).start() From 2fb20635c8c4ce1d795e8f5c3c1853717bdfacd8 Mon Sep 17 00:00:00 2001 From: Voiture Autotech Date: Tue, 7 Oct 2025 00:20:24 +0200 Subject: [PATCH 056/107] =?UTF-8?q?feat=20:=20rajout=20de=20lgpio=20dans?= =?UTF-8?q?=20les=20d=C3=A9pendances?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 + uv.lock | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 392e2b11..1bc1696b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ authors = [ dependencies = [ "gpiozero>=2.0.1", + "lgpio[rpi]>=0.2.2.0", "luma-core>=2.5.1", "luma-oled>=3.14.0", "matplotlib[rpi]>=3.10.5", diff --git a/uv.lock b/uv.lock index 4f641b61..318fed00 100644 --- a/uv.lock +++ b/uv.lock @@ -143,6 +143,7 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "gpiozero" }, + { name = "lgpio" }, { name = "luma-core" }, { name = "luma-oled" }, { name = "matplotlib" }, @@ -190,6 +191,7 @@ requires-dist = [ { name = "adafruit-ssd1306", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, { name = "gpiozero", specifier = ">=2.0.1" }, { name = "gpiozero", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, + { name = "lgpio", extras = ["rpi"], specifier = ">=0.2.2.0" }, { name = "luma-core", specifier = ">=2.5.1" }, { name = "luma-core", marker = "extra == 'rpi'", specifier = ">=2.3.0" }, { name = "luma-oled", specifier = ">=3.14.0" }, @@ -1004,6 +1006,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" }, ] +[[package]] +name = "lgpio" +version = "0.2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/56/33/26ec2e8049eaa2f077bf23a12dc61ca559fbfa7bea0516bf263d657ae275/lgpio-0.2.2.0.tar.gz", hash = "sha256:11372e653b200f76a0b3ef8a23a0735c85ec678a9f8550b9893151ed0f863fff", size = 90087, upload-time = "2024-03-29T21:59:55.901Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b9/d23f9539bbddf47c01a14fc96158a42d9de454fd9d04f7be1347ca6db8fd/lgpio-0.2.2.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:97fe5fb0e888c96031e8899e8c0eca64c63076a6d1f1e774acad8696430b2ff6", size = 376674, upload-time = "2024-03-29T22:00:41.969Z" }, + { url = "https://files.pythonhosted.org/packages/9c/db/fbbade15dbc9febdbd06bd82531c0a78206f96262003145d6953396d9554/lgpio-0.2.2.0-cp310-cp310-manylinux_2_34_aarch64.whl", hash = "sha256:f8f1a2818ed4293182999679ac8559aea70d45743f5a3ae8025837e529d9e0d4", size = 356711, upload-time = "2024-04-01T22:49:43.455Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ca/1c5278b2548e956a52a07efae91ce2300f81c8cf4ad3d7d6b98ce8987e15/lgpio-0.2.2.0-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:d245f315e4bc5ba1b72df9fd935a16c99e56ccf6b41d9f66a87804c1dfd91c86", size = 362126, upload-time = "2024-04-13T14:08:11.879Z" }, + { url = "https://files.pythonhosted.org/packages/78/4e/5721ae44b29e4fe9175f68c881694e3713066590739a7c87f8cee2835c25/lgpio-0.2.2.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:5b3c403e1fba9c17d178f1bde102726c548fc5c4fc1ccf5ec3e18f3c08e07e04", size = 382992, upload-time = "2024-03-29T22:00:45.039Z" }, + { url = "https://files.pythonhosted.org/packages/88/53/e57a22fe815fc68d0991655c1105b8ed872a68491d32e4e0e7d10ffb5c4d/lgpio-0.2.2.0-cp311-cp311-manylinux_2_34_aarch64.whl", hash = "sha256:a2f71fb95b149d8ac82c7c6bae70f054f6dc42a006ad35c90c7d8e54921fbcf4", size = 364848, upload-time = "2024-04-01T22:49:45.889Z" }, + { url = "https://files.pythonhosted.org/packages/a4/71/11f4e3d76400e4ca43f9f9b014f5a86d9a265340c0bea45cce037277eb34/lgpio-0.2.2.0-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:e9f4f3915abe5ae0ffdb4b96f485076d80a663876d839e2d3fd9218a71b9873e", size = 370183, upload-time = "2024-04-13T14:08:14.139Z" }, + { url = "https://files.pythonhosted.org/packages/fe/73/e56c9afb845df53492d42bdea01df9895272bccfdd5128f34719c3a07990/lgpio-0.2.2.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:6c65ac42e878764d04a71ed12fe6d46089b36e9e8127722bf29bb2e4bc91de22", size = 383956, upload-time = "2024-03-29T22:00:47.315Z" }, + { url = "https://files.pythonhosted.org/packages/3b/1c/becd00f66d2c65feed9a668ff9d91732394cb6baba7bec505d55de0e30c9/lgpio-0.2.2.0-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:d907db79292c721c605af08187385ddb3b7af09907e1ffca56cf0cd6558ace0a", size = 366058, upload-time = "2024-04-01T22:49:47.615Z" }, + { url = "https://files.pythonhosted.org/packages/4c/7a/e3b4e5225c9792c4092b2cc07504746acbe62d0a8e4cb023bdf65f6430cf/lgpio-0.2.2.0-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:2aadff092f642fcdada8457c158f87259dfda3a89ec19bae0b99ff22b34aac4b", size = 372103, upload-time = "2024-04-13T14:08:16.351Z" }, +] + [[package]] name = "luma-core" version = "2.5.1" From 89c90abfcde0156c9dc23540e183b01a5604274d Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 20:26:26 +0100 Subject: [PATCH 057/107] feat: suppression de kill all dans les options et rajout que si un programme est reclilquer il se tue --- src/HL/Serveur_mq.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 92eb52ec..4ba33992 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -114,15 +114,9 @@ "info" : "" }, 5: { - "name" : "Kill all", - "type" : "", - "path" : "", - "info" : "" - }, - 6: { - "name" : "reboot", + "name" : "poweroff", "type" : "bash", - "path" : "sudo reboot", + "path" : "sudo poweroff", "info" : "" } } @@ -218,7 +212,7 @@ def i2c_loop(): while True: try : - if (time.time()- last_cmd_time < 1): + if (time.time()- last_cmd_time < 0.5): data = struct.pack(' Date: Thu, 20 Nov 2025 20:29:16 +0100 Subject: [PATCH 058/107] fix: on fait en sorte que lorsque l'on reapuiille sur le bouton cela relance le programme --- src/HL/Serveur_mq.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 4ba33992..69df940c 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -310,6 +310,7 @@ def start_process(num_programme): print(e) if (num_programme == last_programme): + last_programme = 0 # pour pouvoir lancer le programme en rapuyant sur le bouton return # si on est sur le même programme on kill et c'est tout if programme[num_programme]["info"] != "no": From c46ad6566fb76283a7c230c68a093aca04b34b7b Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 20 Nov 2025 21:26:45 +0100 Subject: [PATCH 059/107] fix : petit changement dans lorganisation des fonction --- src/HL/Serveur_mq.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 69df940c..e433aaca 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -130,7 +130,7 @@ Screen = 0 State = 0 #----------------------------------------------------------------------------------------------------- -# fonction utile +# affichage de l'écrans #----------------------------------------------------------------------------------------------------- def make_voltage_im(): global voltage_lipo, voltage_nimh @@ -191,6 +191,10 @@ def bouton_entre(num=None): State=Screen start_process(Screen) +#--------------------------------------------------------------------------------------------------- +# initialisation +#--------------------------------------------------------------------------------------------------- + def _initialize_lidar(): """Initialize the Lidar sensor.""" global lidar From 20b95a2790bd6c17c292144dc417fa0ff8a8c4d9 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 21 Nov 2025 22:12:39 +0100 Subject: [PATCH 060/107] feat : rajout de fonction pas utiliser --- src/HL/Serveur_mq.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index e433aaca..e02406a5 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -129,9 +129,28 @@ # donnée de l'écran Screen = 0 State = 0 +scroll_offset = 3 #----------------------------------------------------------------------------------------------------- # affichage de l'écrans #----------------------------------------------------------------------------------------------------- +def affichage_oled(selected): #test + global scroll_offset + im = Image.new("1", (128, 64), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + + for num, i in enumerate(range(max(selected - scroll_offset, 0), min(len(programme), selected + scroll_offset))): + y = num * TEXT_HEIGHT + + if i == selected: + draw.rectangle((0, y, 127, y + TEXT_HEIGHT), fill="white") + draw.text((3, y), programme[i]["name"], fill="black", font=font) + else: + draw.text((3, y), programme[i]["name"], fill="white", font=font) + + with canvas(device) as display: + display.bitmap((0, 0), im, fill="white") + def make_voltage_im(): global voltage_lipo, voltage_nimh received = [voltage_lipo , voltage_nimh] # Adjust length as needed From 899618c57e464af16028540e5ddc73498eac25d4 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 21 Nov 2025 23:36:51 +0100 Subject: [PATCH 061/107] feat: mise en classe le serveur --- src/HL/Serveur_mq.py | 645 ++++++++++++++++++++++--------------------- 1 file changed, 325 insertions(+), 320 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index e02406a5..600279f8 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -20,6 +20,7 @@ from get_ip import get_ip, check_ssh_connections import subprocess from Lidar import Lidar +from Camera import Camera from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET serial = i2c(port=1, address=0x3C) @@ -64,335 +65,339 @@ telemetry.bind("tcp://127.0.0.1:5557") -remote_control = False # on initialise le remote control à False - -vitesse_d = 0 -vitesse_r = 0 -direction = 0 - -voltage_lipo = 0 -voltage_nimh = 0 - -initial_time = time.time() -last_cmd_time = time.time() - -ip = get_ip() - -#donnée des process -process_output = "" -last_programme = 0 -process = None -programme = { - 0: { - "name" : "Ssh to :\n" + ip, - "type" : "", - "path" : "", - "info" : "no" - }, - 1: { - "name" : "Auto Driving", - "type" : "python", - "path" : "", - "info" : "" - }, - 2: { - "name" : "PS4 Controller", - "type" : "python", - "path" : "./scripts/commande_PS4.py", - "info" : "" - }, - 3: { - "name" : "Connect Controller", - "type" : "bash", - "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", - "info" : "no" - }, - 4: { - "name" : "Remote control", - "type" : "function", - "path" : lambda: switch_remote_control(), - "info" : "" - }, - 5: { - "name" : "poweroff", - "type" : "bash", - "path" : "sudo poweroff", - "info" : "" - } -} - -#donnée du lidar -lidar = None -rDistance = [] -xTheta = 0 - -# donnée de l'écran -Screen = 0 -State = 0 -scroll_offset = 3 -#----------------------------------------------------------------------------------------------------- -# affichage de l'écrans -#----------------------------------------------------------------------------------------------------- -def affichage_oled(selected): #test - global scroll_offset - im = Image.new("1", (128, 64), "black") - draw = ImageDraw.Draw(im) - font = ImageFont.load_default() - - for num, i in enumerate(range(max(selected - scroll_offset, 0), min(len(programme), selected + scroll_offset))): - y = num * TEXT_HEIGHT - - if i == selected: - draw.rectangle((0, y, 127, y + TEXT_HEIGHT), fill="white") - draw.text((3, y), programme[i]["name"], fill="black", font=font) - else: - draw.text((3, y), programme[i]["name"], fill="white", font=font) - - with canvas(device) as display: - display.bitmap((0, 0), im, fill="white") - -def make_voltage_im(): - global voltage_lipo, voltage_nimh - received = [voltage_lipo , voltage_nimh] # Adjust length as needed - # filter out values below 6V and round to 2 decimal places - received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] - text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" - im = Image.new("1", (128, TEXT_HEIGHT), "black") - draw = ImageDraw.Draw(im) - font = ImageFont.load_default() - draw.text((3, 0), text, fill="white", font=font) - return im - -def display_combined_im(text): - im = Image.new("1", (128, 64), "black") - draw = ImageDraw.Draw(im) - font = ImageFont.load_default() - - # Wrap the text to fit within the width of the display - wrapped_text = textwrap.fill(text, width=20) # Adjust width as needed - draw.text((3, 0), wrapped_text, fill="white", font=font) - - voltage_im = make_voltage_im() - im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) - - with canvas(device) as draw: - draw.bitmap((0, 0), im, fill="white") - - -def Idle(): #Enable chossing between states - global Screen - global State - - if Screen==0 and check_ssh_connections(): - led1.on() - Screen=1 - if not check_ssh_connections(): - led1.off() - - if (Screen <= len(programme)): - if programme[Screen]["info"] != "no" : - text = programme[Screen]["name"] + "\n" + programme[Screen]["info"] + "\n" + process_output - else : - text = programme[Screen]["name"] + "\n" + process_output - - display_combined_im(text) - -def bouton_next(): - global Screen - Screen+=1 - if Screen>=len(programme): - Screen=0 - -def bouton_entre(num=None): - global Screen, State - if num!=None: - Screen = num - State=Screen - start_process(Screen) - -#--------------------------------------------------------------------------------------------------- -# initialisation -#--------------------------------------------------------------------------------------------------- - -def _initialize_lidar(): - """Initialize the Lidar sensor.""" - global lidar - try: - lidar = Lidar(SOCKET_ADRESS["IP"], SOCKET_ADRESS["PORT"]) - lidar.stop() - lidar.startContinuous(0, 1080) - print("Lidar initialized successfully") - except Exception as e: - print(f"Error initializing Lidar: {e}") +class Serveur(): + + def __init__(self): + self.remote_control = False # on initialise le remote control à False + + self.vitesse_d = 0 + self.vitesse_r = 0 + self.direction = 0 + + self.voltage_lipo = 0 + self.voltage_nimh = 0 + + self.initial_time = time.time() + self.last_cmd_time = time.time() + + self.ip = get_ip() + + #donnée des process + self.process_output = "" + self.last_programme = 0 + self.process = None + self.programme = { + 0: { + "name" : "Ssh to :\n" + ip, + "type" : "", + "path" : "", + "info" : "no" + }, + 1: { + "name" : "Auto Driving", + "type" : "python", + "path" : "", + "info" : "" + }, + 2: { + "name" : "PS4 Controller", + "type" : "python", + "path" : "./scripts/commande_PS4.py", + "info" : "" + }, + 3: { + "name" : "Connect Controller", + "type" : "bash", + "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", + "info" : "no" + }, + 4: { + "name" : "Remote control", + "type" : "function", + "path" : lambda: switch_remote_control(), + "info" : "" + }, + 5: { + "name" : "poweroff", + "type" : "bash", + "path" : "sudo poweroff", + "info" : "" + } + } + + #donnée du lidar + self.lidar = None + self.rDistance = [] + self.xTheta = 0 + + # donnée de l'écran + self.Screen = 0 + self.State = 0 + self.scroll_offset = 3 + + #----------------------------------------------------------------------------------------------------- + # affichage de l'écrans + #----------------------------------------------------------------------------------------------------- + def affichage_oled(self,selected): #test + im = Image.new("1", (128, 64), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + + for num, i in enumerate(range(max(selected - self.scroll_offset, 0), min(len(programme), selected + scroll_offset))): + y = num * TEXT_HEIGHT + + if i == selected: + draw.rectangle((0, y, 127, y + TEXT_HEIGHT), fill="white") + draw.text((3, y), programme[i]["name"], fill="black", font=font) + else: + draw.text((3, y), programme[i]["name"], fill="white", font=font) + + with canvas(device) as display: + display.bitmap((0, 0), im, fill="white") + + def make_voltage_im(slef): + received = [self.voltage_lipo , self.voltage_nimh] # Adjust length as needed + # filter out values below 6V and round to 2 decimal places + received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] + text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" + im = Image.new("1", (128, TEXT_HEIGHT), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + draw.text((3, 0), text, fill="white", font=font) + return im + + def display_combined_im(text): + im = Image.new("1", (128, 64), "black") + draw = ImageDraw.Draw(im) + font = ImageFont.load_default() + + # Wrap the text to fit within the width of the display + wrapped_text = textwrap.fill(text, width=20) # Adjust width as needed + draw.text((3, 0), wrapped_text, fill="white", font=font) + + voltage_im = make_voltage_im() + im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) + + with canvas(device) as draw: + draw.bitmap((0, 0), im, fill="white") + + + def Idle(self): #Enable chossing between states + if self.Screen==0 and check_ssh_connections(): + led1.on() + slef.Screen=1 + if not check_ssh_connections(): + led1.off() + + if (self.Screen <= len(programme)): + if programme[self.Screen]["info"] != "no" : + text = programme[self.Screen]["name"] + "\n" + programme[self.Screen]["info"] + "\n" + process_output + else : + text = programme[self.Screen]["name"] + "\n" + process_output + + display_combined_im(text) + + def bouton_next(self): + self.Screen+=1 + if self.Screen>=len(programme): + self.Screen=0 + + def bouton_entre(self,num=None): + if num!=None: + self.Screen = num + self.State=self.Screen + start_process(self.Screen) + + #--------------------------------------------------------------------------------------------------- + # initialisation + #--------------------------------------------------------------------------------------------------- + + def _initialize_lidar(self): + """Initialize the Lidar sensor.""" + try: + self.lidar = Lidar(SOCKET_ADRESS["IP"], SOCKET_ADRESS["PORT"]) + self.lidar.stop() + self.lidar.startContinuous(0, 1080) + print("Lidar initialized successfully") + except Exception as e: + print(f"Error initializing Lidar: {e}") -#--------------------------------------------------------------------------------------------------- -# fonction pour la communication -#--------------------------------------------------------------------------------------------------- -def i2c_loop(): - """Envoie vitesse/direction régulièrement au microcontroleur.""" - global vitesse_d, direction, last_cmd_time - - while True: - try : - - if (time.time()- last_cmd_time < 0.5): - data = struct.pack('= length: - float_values = struct.unpack('f' * length_i2c_received, bytes(data[:length])) - list_valeur = list(float_values) - - # on enregistre les valeur - voltage_lipo = list_valeur[0] - voltage_nimh = list_valeur[1] - vitesse_r = list_valeur[2] - time.sleep(0.1) - - - -def car_controle(socket, is_private): - """ on regarde si il s'agit de lappelle pour le control interne - (is_private) ou si on veux prendre le controle depuis le pc.""" - global vitesse_d, direction, last_cmd_time, remote_control - - while is_private or remote_control: - data, ip = socket.recvfrom(1024) - vitesse_d, direction = struct.unpack("ff", data) - last_cmd_time = time.time() - print(ip) - -def envoie_donnee(socket): - """ on regarde si il s'agit de lappelle pour le control interne - (is_private) ou si on veux prendre le controle depuis le pc.""" - global vitesse_d, direction, last_cmd_time, remote_control - - while True: - info = socket.recv_json() - if info["cmd"] == "info": - socket.send_json({ - "voltage_lipo": voltage_lipo, - "voltage_nimh": voltage_nimh, - "vitesse_reelle": vitesse_r, - "timestamp": time.time() - initial_time - }) - else : - socket.send_json({"Error" : "not understand"}) - -def lidar_update_data(): - global rDistance, xTheta - _initialize_lidar() - while True: - try : - rDistance = lidar.rDistance - xTheta = lidar.xTheta - time.sleep(0.1) - except : - print("pas lidar") - time.sleep(1) -#--------------------------------------------------------------------------------------------------- -# Processus -#--------------------------------------------------------------------------------------------------- -def stream_process_output(proc): - global process_output - for line in proc.stdout: - process_output = line.decode().strip() - """ - lines = proc.stdout.split("\n") - size = 3 - chunks = [l[i * size : (i+1) * size] for l in lines for i in range(len(l) // size + 1)] - print(chunks)""" - -def start_process(num_programme): - global process, programme, process_output, last_programme - - if programme[last_programme]["info"] != "no": - programme[last_programme]["info"] = "" - - if process is not None: + def _initialize_camera(self): + """Initialize the camera.""" try: - os.killpg(os.getpgid(process.pid), signal.SIGTERM) + reverse_count = 0 + self.camera = Camera() + self.camera.start() + time.sleep(0.2) # Allow time for the camera to start + log.info("Camera initialized successfully") except Exception as e: - print(e) - - if (num_programme == last_programme): - last_programme = 0 # pour pouvoir lancer le programme en rapuyant sur le bouton - return # si on est sur le même programme on kill et c'est tout - - if programme[num_programme]["info"] != "no": - programme[num_programme]["info"] = "(running)" - process_output = "" - last_programme = num_programme - programme_actuel = programme[num_programme] - if programme_actuel["type"] == "bash": - process = subprocess.Popen( - programme_actuel["path"], - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=os.setsid - ) - - threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() - elif programme_actuel["type"] == "python": - process = subprocess.Popen(["uv","run",programme_actuel["path"]], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=os.setsid - ) - - threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() - elif programme_actuel["type"] == "function": - programme_actuel["path"]() - - - + log.error(f"Error initializing Camera: {e}") + raise + + #--------------------------------------------------------------------------------------------------- + # fonction pour la communication + #--------------------------------------------------------------------------------------------------- + def i2c_loop(self): + """Envoie vitesse/direction régulièrement au microcontroleur.""" + global vitesse_d, direction, last_cmd_time + + while True: + try : + + if (self.time.time()- self.last_cmd_time < 0.5): + data = struct.pack('= length: + float_values = struct.unpack('f' * self.length_i2c_received, bytes(data[:length])) + list_valeur = list(float_values) + + # on enregistre les valeur + self.voltage_lipo = list_valeur[0] + self.voltage_nimh = list_valeur[1] + self.vitesse_r = list_valeur[2] + time.sleep(0.1) -#--------------------------------------------------------------------------------------------------- -# car function -#--------------------------------------------------------------------------------------------------- -def switch_remote_control(): - global remote_control, last_programme - if remote_control: - remote_control = False - programme[last_programme]["info"] = "" - else: - remote_control = True - threading.Thread(target=car_controle, args=(public,False,), daemon=True).start() + def car_controle(self,socket, is_private): + """ on regarde si il s'agit de lappelle pour le control interne + (is_private) ou si on veux prendre le controle depuis le pc.""" + + while is_private or self.remote_control: + data, ip = socket.recvfrom(1024) + self.vitesse_d, self.direction = struct.unpack("ff", data) + self.last_cmd_time = time.time() + print(ip) + + def envoie_donnee(self, socket): + """ on regarde si il s'agit de lappelle pour le control interne + (is_private) ou si on veux prendre le controle depuis le pc.""" + + while True: + info = socket.recv_json() + if info["cmd"] == "info": + socket.send_json({ + "voltage_lipo": self.voltage_lipo, + "voltage_nimh": self.voltage_nimh, + "vitesse_reelle": self.vitesse_r, + "direction" : self.direction, + "timestamp": time.time() - self.initial_time + }) + else : + socket.send_json({"Error" : "not understand"}) + + def lidar_update_data(self): + _initialize_lidar() + while True: + try : + self.rDistance = self.lidar.rDistance + self.xTheta = self.lidar.xTheta + time.sleep(0.1) + except : + print("pas lidar") + time.sleep(1) + #--------------------------------------------------------------------------------------------------- + # Processus + #--------------------------------------------------------------------------------------------------- + def stream_process_output(self, proc): + for line in proc.stdout: + self.process_output = line.decode().strip() + """ + lines = proc.stdout.split("\n") + size = 3 + chunks = [l[i * size : (i+1) * size] for l in lines for i in range(len(l) // size + 1)] + print(chunks)""" + + def start_process(self,num_programme): + global process, programme, process_output, last_programme + + if self.programme[self.last_programme]["info"] != "no": + self.programme[self.last_programme]["info"] = "" + + if self.process is not None: + try: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + except Exception as e: + print(e) + + if (num_programme == self.last_programme): + self.last_programme = 0 # pour pouvoir lancer le programme en rapuyant sur le bouton + return # si on est sur le même programme on kill et c'est tout + + if self.programme[num_programme]["info"] != "no": + self.programme[num_programme]["info"] = "(running)" + self.process_output = "" + self.last_programme = num_programme + self.programme_actuel = self.programme[num_programme] + if self.programme_actuel["type"] == "bash": + process = subprocess.Popen( + self.programme_actuel["path"], + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + preexec_fn=os.setsid + ) + + threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + elif self.programme_actuel["type"] == "python": + process = subprocess.Popen(["uv","run",programme_actuel["path"]], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + preexec_fn=os.setsid + ) + + threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + elif self.programme_actuel["type"] == "function": + self.programme_actuel["path"]() + + + + + + #--------------------------------------------------------------------------------------------------- + # car function + #--------------------------------------------------------------------------------------------------- + + def switch_remote_control(self): + if self.remote_control: + self.remote_control = False + programme[self.last_programme]["info"] = "" + else: + self.remote_control = True + threading.Thread(target=car_controle, args=(public,False,), daemon=True).start() + + def main(self): + self.bp_next.when_pressed = bouton_next + self.bp_entre.when_pressed = bouton_entre + + threading.Thread(target=self.i2c_loop, daemon=True).start() + threading.Thread(target=self.i2c_received, daemon=True).start() + threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() + threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() + threading.Thread(target=self.lidar_update_data, daemon=True).start() + while True: + Idle() #--------------------------------------------------------------------------------------------------- # main #--------------------------------------------------------------------------------------------------- if __name__ == "__main__": - - bp_next.when_pressed = bouton_next - bp_entre.when_pressed = bouton_entre - - threading.Thread(target=i2c_loop, daemon=True).start() - threading.Thread(target=i2c_received, daemon=True).start() - threading.Thread(target=car_controle, args=(private,True,), daemon=True).start() - threading.Thread(target=envoie_donnee, args=(telemetry,), daemon=True).start() - threading.Thread(target=lidar_update_data, daemon=True).start() - - while True: - Idle() + boot = Serveur() + boot.main() From 48117f796161f65a4b5930ccc1a1c4f78ba85de7 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Sat, 22 Nov 2025 00:55:56 +0100 Subject: [PATCH 062/107] =?UTF-8?q?fix=20:=20dans=20uv=20avec=20les=20bonn?= =?UTF-8?q?e=20d=C3=A9pendance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 8 -------- src/HL/Serveur_mq.py | 1 + uv.lock | 41 ----------------------------------------- 3 files changed, 1 insertion(+), 49 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1bc1696b..f374fd12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,14 +14,6 @@ authors = [ ] dependencies = [ - "gpiozero>=2.0.1", - "lgpio[rpi]>=0.2.2.0", - "luma-core>=2.5.1", - "luma-oled>=3.14.0", - "matplotlib[rpi]>=3.10.5", - "netifaces>=0.11.0", - "smbus>=1.1.post2", - "zmq>=0.0.0", ] [project.optional-dependencies] diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 600279f8..8500b955 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -391,6 +391,7 @@ def main(self): threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() + while True: Idle() diff --git a/uv.lock b/uv.lock index 318fed00..2c10d6d5 100644 --- a/uv.lock +++ b/uv.lock @@ -141,16 +141,6 @@ sdist = { url = "https://files.pythonhosted.org/packages/fc/de/0a176512f6fab96eb name = "autotech" version = "0.1.0" source = { virtual = "." } -dependencies = [ - { name = "gpiozero" }, - { name = "lgpio" }, - { name = "luma-core" }, - { name = "luma-oled" }, - { name = "matplotlib" }, - { name = "netifaces" }, - { name = "smbus" }, - { name = "zmq" }, -] [package.optional-dependencies] docs = [ @@ -189,20 +179,14 @@ requires-dist = [ { name = "adafruit-blinka", marker = "extra == 'rpi'", specifier = ">=8.0.0" }, { name = "adafruit-circuitpython-vl53l0x", marker = "extra == 'rpi'", specifier = ">=3.6.0" }, { name = "adafruit-ssd1306", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, - { name = "gpiozero", specifier = ">=2.0.1" }, { name = "gpiozero", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, - { name = "lgpio", extras = ["rpi"], specifier = ">=0.2.2.0" }, - { name = "luma-core", specifier = ">=2.5.1" }, { name = "luma-core", marker = "extra == 'rpi'", specifier = ">=2.3.0" }, - { name = "luma-oled", specifier = ">=3.14.0" }, { name = "luma-oled", marker = "extra == 'rpi'", specifier = ">=3.8.0" }, { name = "matplotlib", marker = "extra == 'simu'", specifier = ">=3.4.0" }, - { name = "matplotlib", extras = ["rpi"], specifier = ">=3.10.5" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.4.0" }, { name = "mkdocs-git-authors-plugin", marker = "extra == 'docs'", specifier = ">=0.6.0" }, { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'docs'", specifier = ">=1.1.0" }, { name = "mkdocs-mermaid2-plugin", marker = "extra == 'docs'", specifier = ">=0.6.0" }, - { name = "netifaces", specifier = ">=0.11.0" }, { name = "numpy", marker = "extra == 'simu'", specifier = ">=1.21.0" }, { name = "onnx", marker = "extra == 'simu'", specifier = ">=1.8.0" }, { name = "onnxruntime", marker = "extra == 'rpi'", specifier = ">=1.8.0" }, @@ -210,12 +194,10 @@ requires-dist = [ { name = "pyps4controller", marker = "extra == 'rpi'", specifier = ">=1.2.0" }, { name = "rpi-gpio", marker = "extra == 'rpi'", specifier = ">=0.7.1" }, { name = "rpi-hardware-pwm", marker = "extra == 'rpi'", specifier = ">=0.1.0" }, - { name = "smbus", specifier = ">=1.1.post2" }, { name = "smbus", marker = "extra == 'rpi'", specifier = ">=1.1.post2" }, { name = "spidev", marker = "extra == 'rpi'", specifier = ">=3.5" }, { name = "stable-baselines3", marker = "extra == 'simu'", specifier = ">=1.6.0" }, { name = "torch", marker = "extra == 'simu'", specifier = ">=1.9.0" }, - { name = "zmq", specifier = ">=0.0.0" }, { name = "zmq", marker = "extra == 'rpi'", specifier = ">=0.0.0" }, ] provides-extras = ["docs", "simu", "rpi"] @@ -1006,23 +988,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" }, ] -[[package]] -name = "lgpio" -version = "0.2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/56/33/26ec2e8049eaa2f077bf23a12dc61ca559fbfa7bea0516bf263d657ae275/lgpio-0.2.2.0.tar.gz", hash = "sha256:11372e653b200f76a0b3ef8a23a0735c85ec678a9f8550b9893151ed0f863fff", size = 90087, upload-time = "2024-03-29T21:59:55.901Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/b9/d23f9539bbddf47c01a14fc96158a42d9de454fd9d04f7be1347ca6db8fd/lgpio-0.2.2.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:97fe5fb0e888c96031e8899e8c0eca64c63076a6d1f1e774acad8696430b2ff6", size = 376674, upload-time = "2024-03-29T22:00:41.969Z" }, - { url = "https://files.pythonhosted.org/packages/9c/db/fbbade15dbc9febdbd06bd82531c0a78206f96262003145d6953396d9554/lgpio-0.2.2.0-cp310-cp310-manylinux_2_34_aarch64.whl", hash = "sha256:f8f1a2818ed4293182999679ac8559aea70d45743f5a3ae8025837e529d9e0d4", size = 356711, upload-time = "2024-04-01T22:49:43.455Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ca/1c5278b2548e956a52a07efae91ce2300f81c8cf4ad3d7d6b98ce8987e15/lgpio-0.2.2.0-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:d245f315e4bc5ba1b72df9fd935a16c99e56ccf6b41d9f66a87804c1dfd91c86", size = 362126, upload-time = "2024-04-13T14:08:11.879Z" }, - { url = "https://files.pythonhosted.org/packages/78/4e/5721ae44b29e4fe9175f68c881694e3713066590739a7c87f8cee2835c25/lgpio-0.2.2.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:5b3c403e1fba9c17d178f1bde102726c548fc5c4fc1ccf5ec3e18f3c08e07e04", size = 382992, upload-time = "2024-03-29T22:00:45.039Z" }, - { url = "https://files.pythonhosted.org/packages/88/53/e57a22fe815fc68d0991655c1105b8ed872a68491d32e4e0e7d10ffb5c4d/lgpio-0.2.2.0-cp311-cp311-manylinux_2_34_aarch64.whl", hash = "sha256:a2f71fb95b149d8ac82c7c6bae70f054f6dc42a006ad35c90c7d8e54921fbcf4", size = 364848, upload-time = "2024-04-01T22:49:45.889Z" }, - { url = "https://files.pythonhosted.org/packages/a4/71/11f4e3d76400e4ca43f9f9b014f5a86d9a265340c0bea45cce037277eb34/lgpio-0.2.2.0-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:e9f4f3915abe5ae0ffdb4b96f485076d80a663876d839e2d3fd9218a71b9873e", size = 370183, upload-time = "2024-04-13T14:08:14.139Z" }, - { url = "https://files.pythonhosted.org/packages/fe/73/e56c9afb845df53492d42bdea01df9895272bccfdd5128f34719c3a07990/lgpio-0.2.2.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:6c65ac42e878764d04a71ed12fe6d46089b36e9e8127722bf29bb2e4bc91de22", size = 383956, upload-time = "2024-03-29T22:00:47.315Z" }, - { url = "https://files.pythonhosted.org/packages/3b/1c/becd00f66d2c65feed9a668ff9d91732394cb6baba7bec505d55de0e30c9/lgpio-0.2.2.0-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:d907db79292c721c605af08187385ddb3b7af09907e1ffca56cf0cd6558ace0a", size = 366058, upload-time = "2024-04-01T22:49:47.615Z" }, - { url = "https://files.pythonhosted.org/packages/4c/7a/e3b4e5225c9792c4092b2cc07504746acbe62d0a8e4cb023bdf65f6430cf/lgpio-0.2.2.0-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:2aadff092f642fcdada8457c158f87259dfda3a89ec19bae0b99ff22b34aac4b", size = 372103, upload-time = "2024-04-13T14:08:16.351Z" }, -] - [[package]] name = "luma-core" version = "2.5.1" @@ -1333,12 +1298,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] -[[package]] -name = "netifaces" -version = "0.11.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/91/86a6eac449ddfae239e93ffc1918cf33fd9bab35c04d1e963b311e347a73/netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", size = 30106, upload-time = "2021-05-31T08:33:02.506Z" } - [[package]] name = "networkx" version = "3.4.2" From 967d23262e810e9016765c0d2c76415dafcfcf19 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Sat, 22 Nov 2025 02:42:57 +0100 Subject: [PATCH 063/107] feat : Serveur_mq slef en alerte --- pyproject.toml | 2 ++ src/HL/Serveur_mq.py | 6 ++++-- uv.lock | 10 ++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f374fd12..6eab4db4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,4 +57,6 @@ rpi = [ # PS4 controller support "pyPS4Controller>=1.2.0", "zmq>=0.0.0", + "netifaces>=0.11.0", + "matplotlib>=3.10.5", ] diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 8500b955..cacb3408 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -43,6 +43,8 @@ TEXT_HEIGHT = 11 TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff +#sudo apt-get install libcap-dev pour lancer picamera2 + # on recoit les inoformations """ private = context.socket(zmq.SUB) @@ -155,7 +157,7 @@ def affichage_oled(self,selected): #test with canvas(device) as display: display.bitmap((0, 0), im, fill="white") - def make_voltage_im(slef): + def make_voltage_im(self): received = [self.voltage_lipo , self.voltage_nimh] # Adjust length as needed # filter out values below 6V and round to 2 decimal places received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] @@ -185,7 +187,7 @@ def display_combined_im(text): def Idle(self): #Enable chossing between states if self.Screen==0 and check_ssh_connections(): led1.on() - slef.Screen=1 + self.Screen=1 if not check_ssh_connections(): led1.off() diff --git a/uv.lock b/uv.lock index 2c10d6d5..d39db1ce 100644 --- a/uv.lock +++ b/uv.lock @@ -156,6 +156,8 @@ rpi = [ { name = "gpiozero" }, { name = "luma-core" }, { name = "luma-oled" }, + { name = "matplotlib" }, + { name = "netifaces" }, { name = "onnxruntime" }, { name = "pyps4controller" }, { name = "rpi-gpio" }, @@ -182,11 +184,13 @@ requires-dist = [ { name = "gpiozero", marker = "extra == 'rpi'", specifier = ">=1.6.0" }, { name = "luma-core", marker = "extra == 'rpi'", specifier = ">=2.3.0" }, { name = "luma-oled", marker = "extra == 'rpi'", specifier = ">=3.8.0" }, + { name = "matplotlib", marker = "extra == 'rpi'", specifier = ">=3.10.5" }, { name = "matplotlib", marker = "extra == 'simu'", specifier = ">=3.4.0" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.4.0" }, { name = "mkdocs-git-authors-plugin", marker = "extra == 'docs'", specifier = ">=0.6.0" }, { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'docs'", specifier = ">=1.1.0" }, { name = "mkdocs-mermaid2-plugin", marker = "extra == 'docs'", specifier = ">=0.6.0" }, + { name = "netifaces", marker = "extra == 'rpi'", specifier = ">=0.11.0" }, { name = "numpy", marker = "extra == 'simu'", specifier = ">=1.21.0" }, { name = "onnx", marker = "extra == 'simu'", specifier = ">=1.8.0" }, { name = "onnxruntime", marker = "extra == 'rpi'", specifier = ">=1.8.0" }, @@ -1298,6 +1302,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] +[[package]] +name = "netifaces" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/91/86a6eac449ddfae239e93ffc1918cf33fd9bab35c04d1e963b311e347a73/netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32", size = 30106, upload-time = "2021-05-31T08:33:02.506Z" } + [[package]] name = "networkx" version = "3.4.2" From e4e0d31734968f6546e96759b151f5e4680213b9 Mon Sep 17 00:00:00 2001 From: ExoRoy Date: Sat, 22 Nov 2025 02:54:24 +0100 Subject: [PATCH 064/107] correction des selfs du C --- src/HL/Serveur_mq.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index cacb3408..f741e4be 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -116,7 +116,7 @@ def __init__(self): 4: { "name" : "Remote control", "type" : "function", - "path" : lambda: switch_remote_control(), + "path" : lambda: self.switch_remote_control(), "info" : "" }, 5: { @@ -145,7 +145,7 @@ def affichage_oled(self,selected): #test draw = ImageDraw.Draw(im) font = ImageFont.load_default() - for num, i in enumerate(range(max(selected - self.scroll_offset, 0), min(len(programme), selected + scroll_offset))): + for num, i in enumerate(range(max(selected - self.scroll_offset, 0), min(len(programme), selected + self.scroll_offset))): y = num * TEXT_HEIGHT if i == selected: @@ -168,7 +168,7 @@ def make_voltage_im(self): draw.text((3, 0), text, fill="white", font=font) return im - def display_combined_im(text): + def display_combined_im(self,text): im = Image.new("1", (128, 64), "black") draw = ImageDraw.Draw(im) font = ImageFont.load_default() @@ -177,7 +177,7 @@ def display_combined_im(text): wrapped_text = textwrap.fill(text, width=20) # Adjust width as needed draw.text((3, 0), wrapped_text, fill="white", font=font) - voltage_im = make_voltage_im() + voltage_im = self.make_voltage_im() im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) with canvas(device) as draw: @@ -197,7 +197,7 @@ def Idle(self): #Enable chossing between states else : text = programme[self.Screen]["name"] + "\n" + process_output - display_combined_im(text) + self.display_combined_im(text) def bouton_next(self): self.Screen+=1 @@ -208,7 +208,7 @@ def bouton_entre(self,num=None): if num!=None: self.Screen = num self.State=self.Screen - start_process(self.Screen) + self.start_process(self.Screen) #--------------------------------------------------------------------------------------------------- # initialisation @@ -305,7 +305,7 @@ def envoie_donnee(self, socket): socket.send_json({"Error" : "not understand"}) def lidar_update_data(self): - _initialize_lidar() + self._initialize_lidar() while True: try : self.rDistance = self.lidar.rDistance @@ -356,15 +356,15 @@ def start_process(self,num_programme): preexec_fn=os.setsid ) - threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + threading.Thread(target=self.stream_process_output, args=(process,), daemon=True).start() elif self.programme_actuel["type"] == "python": - process = subprocess.Popen(["uv","run",programme_actuel["path"]], + process = subprocess.Popen(["uv","run",self.programme_actuel["path"]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid ) - threading.Thread(target=stream_process_output, args=(process,), daemon=True).start() + threading.Thread(target=self.stream_process_output, args=(process,), daemon=True).start() elif self.programme_actuel["type"] == "function": self.programme_actuel["path"]() @@ -382,7 +382,7 @@ def switch_remote_control(self): programme[self.last_programme]["info"] = "" else: self.remote_control = True - threading.Thread(target=car_controle, args=(public,False,), daemon=True).start() + threading.Thread(target=self.car_controle, args=(public,False,), daemon=True).start() def main(self): self.bp_next.when_pressed = bouton_next @@ -395,7 +395,7 @@ def main(self): threading.Thread(target=self.lidar_update_data, daemon=True).start() while True: - Idle() + self.Idle() #--------------------------------------------------------------------------------------------------- # main From 8a0057436e96c08901951e2ec65da16ced7f7e2b Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Sat, 22 Nov 2025 05:29:23 +0100 Subject: [PATCH 065/107] =?UTF-8?q?feat:=20rajout=20de=20la=20prise=20de?= =?UTF-8?q?=20video=20en=20sortie=20par=20serveur=5Fmq=20et=20entr=C3=A9e?= =?UTF-8?q?=20avec=20test=5Fserveur=20(on=20tourne=20=C3=A0=2015=20image?= =?UTF-8?q?=20seconde=20=C3=A0=20=C3=A0m=C3=A9lior=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 144 +++++++++++++++++++++++++++++------------ src/HL/test_serveur.py | 34 +++++++++- 2 files changed, 132 insertions(+), 46 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index f741e4be..1f8354b7 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -1,6 +1,7 @@ import zmq context = zmq.Context() - +import numpy as np +import cv2 import time import threading import smbus @@ -33,17 +34,20 @@ # I2C address of the slave SLAVE_ADDRESS = 0x08 -length_i2c_received = 3 #le nombre de donnée récupéré par l'i2c + #le nombre de donnée récupéré par l'i2c + -bp_next = Button("GPIO5", bounce_time=0.1) -bp_entre = Button("GPIO6", bounce_time=0.1) -led1 = LED("GPIO17") -led2 = LED("GPIO27") -buzzer = Buzzer("GPIO26") TEXT_HEIGHT = 11 TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff +#sudo apt install libcap-dev +#sudo apt install python3-libcamera + #sudo apt-get install libcap-dev pour lancer picamera2 +#rm -rf .venv +#uv venv --system-site-packages +#source .venv/bin/activate +#uv pip uninstall numpy # on recoit les inoformations """ @@ -64,12 +68,18 @@ # on utilise tcp pour les infos des différents informations telemetry = context.socket(zmq.REP) -telemetry.bind("tcp://127.0.0.1:5557") +telemetry.bind("tcp://0.0.0.0:5557") class Serveur(): def __init__(self): + self.bp_next = Button("GPIO5", bounce_time=0.1) + self.bp_entre = Button("GPIO6", bounce_time=0.1) + self.length_i2c_received = 3 + self.led1 = LED("GPIO17") + self.led2 = LED("GPIO27") + self.buzzer = Buzzer("GPIO26") self.remote_control = False # on initialise le remote control à False self.vitesse_d = 0 @@ -78,6 +88,7 @@ def __init__(self): self.voltage_lipo = 0 self.voltage_nimh = 0 + self.camera_reverse = True self.initial_time = time.time() self.last_cmd_time = time.time() @@ -90,7 +101,7 @@ def __init__(self): self.process = None self.programme = { 0: { - "name" : "Ssh to :\n" + ip, + "name" : "Ssh to :\n" + self.ip, "type" : "", "path" : "", "info" : "no" @@ -145,14 +156,14 @@ def affichage_oled(self,selected): #test draw = ImageDraw.Draw(im) font = ImageFont.load_default() - for num, i in enumerate(range(max(selected - self.scroll_offset, 0), min(len(programme), selected + self.scroll_offset))): + for num, i in enumerate(range(max(selected - self.scroll_offset, 0), min(len(self.programme), selected + self.scroll_offset))): y = num * TEXT_HEIGHT if i == selected: draw.rectangle((0, y, 127, y + TEXT_HEIGHT), fill="white") - draw.text((3, y), programme[i]["name"], fill="black", font=font) + draw.text((3, y), self.programme[i]["name"], fill="black", font=font) else: - draw.text((3, y), programme[i]["name"], fill="white", font=font) + draw.text((3, y), self.programme[i]["name"], fill="white", font=font) with canvas(device) as display: display.bitmap((0, 0), im, fill="white") @@ -186,22 +197,22 @@ def display_combined_im(self,text): def Idle(self): #Enable chossing between states if self.Screen==0 and check_ssh_connections(): - led1.on() + self.led1.on() self.Screen=1 if not check_ssh_connections(): - led1.off() + self.led1.off() - if (self.Screen <= len(programme)): - if programme[self.Screen]["info"] != "no" : - text = programme[self.Screen]["name"] + "\n" + programme[self.Screen]["info"] + "\n" + process_output + if (self.Screen < len(self.programme)): + if self.programme[self.Screen]["info"] != "no" : + text = self.programme[self.Screen]["name"] + "\n" + self.programme[self.Screen]["info"] + "\n" + self.process_output else : - text = programme[self.Screen]["name"] + "\n" + process_output + text = self.programme[self.Screen]["name"] + "\n" + self.process_output self.display_combined_im(text) def bouton_next(self): self.Screen+=1 - if self.Screen>=len(programme): + if self.Screen>=len(self.programme): self.Screen=0 def bouton_entre(self,num=None): @@ -226,28 +237,26 @@ def _initialize_lidar(self): def _initialize_camera(self): """Initialize the camera.""" - try: - reverse_count = 0 - self.camera = Camera() - self.camera.start() - time.sleep(0.2) # Allow time for the camera to start - log.info("Camera initialized successfully") - except Exception as e: - log.error(f"Error initializing Camera: {e}") - raise + for i in range(10): + try: + self.camera = Camera() + print("Camera OK") + return + except Exception as e: + print("Camera retry", i, e) + time.sleep(0.5) + raise RuntimeError("Camera KO après 10 essais") #--------------------------------------------------------------------------------------------------- # fonction pour la communication #--------------------------------------------------------------------------------------------------- def i2c_loop(self): """Envoie vitesse/direction régulièrement au microcontroleur.""" - global vitesse_d, direction, last_cmd_time - while True: try : - if (self.time.time()- self.last_cmd_time < 0.5): - data = struct.pack(' Date: Sun, 30 Nov 2025 05:57:44 +0100 Subject: [PATCH 066/107] =?UTF-8?q?rajout=20de=20Camera=5Fserv=20qui=20lan?= =?UTF-8?q?ce=20sur=20un=20lien=20la=20camera=20en=20temps=20r=C3=A9el?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UV_USAGE.md | 5 +- scripts/envoie_camera_sur_web.py | 97 ++++++++++++++++++++++++++++ src/HL/Camera.py | 50 ++++++++++----- src/HL/Camera_serv.py | 107 +++++++++++++++++++++++++++++++ src/HL/Serveur_mq.py | 60 ++++++++++------- src/HL/test_serveur.py | 15 +++-- 6 files changed, 288 insertions(+), 46 deletions(-) create mode 100644 scripts/envoie_camera_sur_web.py create mode 100644 src/HL/Camera_serv.py diff --git a/UV_USAGE.md b/UV_USAGE.md index 87a42f31..637b14a8 100644 --- a/UV_USAGE.md +++ b/UV_USAGE.md @@ -9,7 +9,10 @@ This project now uses [UV](https://github.com/astral-sh/uv) for fast, reliable P curl -LsSf https://astral.sh/uv/install.sh | sh source $HOME/.cargo/env ``` - +## Initialise uv for using external dependencies not installable in uv +```bash +uv venv --system-site-packages +``` ### Install Project Dependencies ```bash # Install all runtime dependencies diff --git a/scripts/envoie_camera_sur_web.py b/scripts/envoie_camera_sur_web.py new file mode 100644 index 00000000..19f2b409 --- /dev/null +++ b/scripts/envoie_camera_sur_web.py @@ -0,0 +1,97 @@ +import io +import logging +import socketserver +from http import server +from threading import Condition + +from picamera2 import Picamera2 +from picamera2.encoders import JpegEncoder +from picamera2.outputs import FileOutput + +# HTML page for the MJPEG streaming demo +PAGE = """\ + + +RaspberryTips Pi Cam Stream + + +

Raspberry Tips Pi Camera Live Stream Demo

+ + + +""" + +# Class to handle streaming output +class StreamingOutput(io.BufferedIOBase): + def __init__(self): + self.frame = None + self.condition = Condition() + + def write(self, buf): + with self.condition: + self.frame = buf + self.condition.notify_all() + +# Class to handle HTTP requests +class StreamingHandler(server.BaseHTTPRequestHandler): + def do_GET(self): + if self.path == '/': + # Redirect root path to index.html + self.send_response(301) + self.send_header('Location', '/index.html') + self.end_headers() + elif self.path == '/index.html': + # Serve the HTML page + content = PAGE.encode('utf-8') + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.send_header('Content-Length', len(content)) + self.end_headers() + self.wfile.write(content) + elif self.path == '/stream.mjpg': + # Set up MJPEG streaming + self.send_response(200) + self.send_header('Age', 0) + self.send_header('Cache-Control', 'no-cache, private') + self.send_header('Pragma', 'no-cache') + self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') + self.end_headers() + try: + while True: + with output.condition: + output.condition.wait() + frame = output.frame + self.wfile.write(b'--FRAME\r\n') + self.send_header('Content-Type', 'image/jpeg') + self.send_header('Content-Length', len(frame)) + self.end_headers() + self.wfile.write(frame) + self.wfile.write(b'\r\n') + except Exception as e: + logging.warning( + 'Removed streaming client %s: %s', + self.client_address, str(e)) + else: + # Handle 404 Not Found + self.send_error(404) + self.end_headers() + +# Class to handle streaming server +class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer): + allow_reuse_address = True + daemon_threads = True + +# Create Picamera2 instance and configure it +picam2 = Picamera2() +picam2.configure(picam2.create_video_configuration(main={"size": (640, 480)})) +output = StreamingOutput() +picam2.start_recording(JpegEncoder(), FileOutput(output)) + +try: + # Set up and start the streaming server + address = ('', 8000) + server = StreamingServer(address, StreamingHandler) + server.serve_forever() +finally: + # Stop recording when the script is interrupted + picam2.stop_recording() \ No newline at end of file diff --git a/src/HL/Camera.py b/src/HL/Camera.py index 4d2a78ac..011c8dc5 100644 --- a/src/HL/Camera.py +++ b/src/HL/Camera.py @@ -1,3 +1,4 @@ +import cv2 from picamera2 import Picamera2 # type: ignore from PIL import Image import numpy as np @@ -6,6 +7,7 @@ import threading import shutil import scipy as sp +import time N_IMAGES = 100 # Number of images to capture SAVE_DIR = "Captured_Frames" # Directory to save frames @@ -20,41 +22,55 @@ Y_OFFSET = -80 # Offset for the y-axis in the image class Camera: - def __init__(self): + def __init__(self, url="tcp://192.168.1.10:6002"): os.environ["LIBCAMERA_LOG_LEVELS"] = "WARN" self.debug_counter = 0 # Counter for debug images self.image_no = 0 self.image_path = None - self.picam2 = Picamera2() - config = self.picam2.create_preview_configuration(main={"size": (1920, 1080)}) - self.picam2.configure(config) - self.picam2.start() + + self.url = url.replace("tcp://", "") + self.url = f"tcp://{self.url}" + self.cap = cv2.VideoCapture(self.url, cv2.CAP_FFMPEG) + + if not self.cap.isOpened(): + raise RuntimeError(f"Impossible d'ouvrir le flux vidéo : {self.url}") + + self.last_frame = None self.flag_stop = False self.thread = None # Stocke le thread pour contrôle ultérieur - picamera2_logger = log.getLogger("picamera2") - picamera2_logger.setLevel(log.INFO) + camlogger = log.getLogger("picamera2") + camlogger.setLevel(log.INFO) os.makedirs(SAVE_DIR, exist_ok=True) # Crée le répertoire s'il n'existe pas os.makedirs(DEBUG_DIR, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas os.makedirs(DEBUG_DIR_wayfinding, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas self.capture_image() # Capture une image pour initialiser le répertoire de sauvegarde def capture_image(self): - + ok, frame = self.cap.read() + + if not ok: + time.sleep(0.01) + return self.last_frame # fallback si frame ratée + + frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + self.last_frame = frame + + # compatibilité avec ton ancien système self.image_path = os.path.join(SAVE_DIR, f"frame_{self.image_no:02d}.jpg") - frame = self.picam2.capture_array() - image = Image.fromarray(frame).convert("RGB") - image.save(self.image_path) + Image.fromarray(frame).save(self.image_path) + self.image_no += 1 - return image + if self.image_no >= N_IMAGES: + self.image_no = 0 + + return Image.fromarray(frame) def capture_images_continus(self): - while True: + while not self.flag_stop: for i in range(N_IMAGES): self.capture_image() if self.flag_stop: break - if self.flag_stop: - break self.image_no = 0 def start(self): @@ -69,8 +85,8 @@ def stop(self): self.flag_stop = True if self.thread is not None: self.thread.join() # Attendre la fin du thread avant de continuer - self.picam2.stop() - self.picam2.close() + if self.cap: + self.cap.release() shutil.rmtree(SAVE_DIR) # Supprime le répertoire des images capturées def get_last_image(self): diff --git a/src/HL/Camera_serv.py b/src/HL/Camera_serv.py new file mode 100644 index 00000000..cef31815 --- /dev/null +++ b/src/HL/Camera_serv.py @@ -0,0 +1,107 @@ +import io +import threading +import logging +from http import server +import socketserver +from picamera2 import Picamera2 +from picamera2.encoders import JpegEncoder +from picamera2.outputs import FileOutput +from threading import Condition + +# ------------------------------------------------------------------- +# Stockage global de la dernière frame reçue +# ------------------------------------------------------------------- +class FrameBuffer: + def __init__(self): + self.frame = None + self.condition = Condition() + + def update(self, data): + with self.condition: + self.frame = data + self.condition.notify_all() + + def get(self): + # Ça te donne la dernière frame (ou None au début) + return self.frame + + +frame_buffer = FrameBuffer() + + +# ------------------------------------------------------------------- +# Output pour Picamera2 (reçoit les JPEG du JpegEncoder) +# ------------------------------------------------------------------- +class StreamOutput(io.BufferedIOBase): + def write(self, buf): + frame_buffer.update(buf) + + +# ------------------------------------------------------------------- +# Serveur MJPEG : /stream.mjpg +# ------------------------------------------------------------------- +class StreamHandler(server.BaseHTTPRequestHandler): + def do_GET(self): + if self.path == "/stream.mjpg": + self.send_response(200) + self.send_header('Cache-Control', 'no-cache') + self.send_header('Content-Type', + 'multipart/x-mixed-replace; boundary=FRAME') + self.end_headers() + + try: + while True: + with frame_buffer.condition: + frame_buffer.condition.wait() + frame = frame_buffer.frame + + self.wfile.write(b"--FRAME\r\n") + self.send_header("Content-Type", "image/jpeg") + self.send_header("Content-Length", len(frame)) + self.end_headers() + self.wfile.write(frame) + self.wfile.write(b"\r\n") + + except Exception as e: + logging.warning("Client déconnecté: %s", e) + else: + self.send_error(404) + + +class StreamServer(socketserver.ThreadingMixIn, server.HTTPServer): + daemon_threads = True + allow_reuse_address = True + + +# ------------------------------------------------------------------- +# Thread principal de capture + serveur HTTP +# ------------------------------------------------------------------- +def start_camera_stream(port=8000, size=(640, 480)): + def run(): + picam2 = Picamera2() + picam2.configure(picam2.create_video_configuration( + main={"size": size} + )) + + output = StreamOutput() + picam2.start_recording(JpegEncoder(), FileOutput(output)) + + httpd = StreamServer(("", port), StreamHandler) + print(f"[INFO] Serveur MJPEG en ligne sur http://:{port}/stream.mjpg") + + try: + httpd.serve_forever() + finally: + picam2.stop_recording() + + t = threading.Thread(target=run, daemon=True) + t.start() + return t + + +# ------------------------------------------------------------------- +# Fonction utilitaire pour d’autres scripts +# ------------------------------------------------------------------- +def get_current_frame(): + """Retourne la dernière frame JPEG""" + return frame_buffer.get() diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 1f8354b7..7f170926 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -23,6 +23,7 @@ from Lidar import Lidar from Camera import Camera from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET +from camera_server import start_camera_stream, get_current_frame serial = i2c(port=1, address=0x3C) device = ssd1306(serial) @@ -147,6 +148,7 @@ def __init__(self): self.Screen = 0 self.State = 0 self.scroll_offset = 3 + #self.camera = Camera() #----------------------------------------------------------------------------------------------------- # affichage de l'écrans @@ -340,32 +342,47 @@ def lidar_update_data(self): print("pas lidar") time.sleep(1) - def camera_update_data(self): - self._initialize_camera() - while True: - try : - self.camera_reverse = self.camera.is_running_in_reversed() - time.sleep(0.5) - except : - self._initialize_camera() - time.sleep(5) def _start_video_stream(self): """Start continuous JPEG compressed video streaming via ZMQ.""" - context = zmq.Context() - socket = context.socket(zmq.PUSH) - socket.bind("tcp://0.0.0.0:6001") # port dédié au flux vidéo + # context = zmq.Context() + # socket = context.socket(zmq.PUSH) + # socket.bind("tcp://0.0.0.0:6001") # port dédié au flux vidéo from io import BytesIO - + cmd = [ + "rpicam-vid", + "-t", "0", + "--width", "640", + "--height", "480", + "--framerate", "30", + "--codec", "h264", + "--inline", + "--libav-format", "mpegts", + "-o", "tcp://0.0.0.0:6002?listen" + ] + cam = None while True: try: - frame = self.camera.capture_image() # PIL image - buffer = BytesIO() - frame.save(buffer, format="JPEG", quality=70) - jpg_bytes = buffer.getvalue() - socket.send(jpg_bytes) # direct bytes (pas de JSON) - time.sleep(0.03) # ~30 fps max, selon Pi + if cam is None or cam.poll() is not None: + print("[Video] Starting rpicam-vid service...") + cam = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + preexec_fn=os.setsid + ) + + # log output + for line in cam.stdout: + print("[rpicam-vid]", line.decode().strip()) + time.sleep(1) + # frame = self.camera.capture_image() # PIL image + # buffer = BytesIO() + # frame.save(buffer, format="JPEG", quality=70) + # jpg_bytes = buffer.getvalue() + # socket.send(jpg_bytes) # direct bytes (pas de JSON) + # time.sleep(0.03) # ~30 fps max, selon Pi except Exception as e: log.error(f"Video stream error: {e}") time.sleep(1) @@ -448,10 +465,7 @@ def main(self): threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() - self._initialize_camera() - threading.Thread(target=self.camera_update_data, daemon=True).start() - threading.Thread(target=self._start_video_stream, daemon=True).start() - + start_camera_stream(port=8000) while True: self.Idle() diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py index e888807e..6c22757a 100644 --- a/src/HL/test_serveur.py +++ b/src/HL/test_serveur.py @@ -73,14 +73,19 @@ def toCartesian(xTheta, xR): """ import cv2 + +cap = cv2.VideoCapture("tcp://192.168.1.10:6002") + + if __name__ == "__main__": while(True): - jpg = socket.recv() - img_np = np.frombuffer(jpg, dtype=np.uint8) - frame = cv2.imdecode(img_np, cv2.IMREAD_COLOR) + ret, frame = cap.read() + if not ret: + print("No frame…") + continue - cv2.imshow("Pi Camera Stream", frame) - if cv2.waitKey(1) & 0xFF == ord('q'): + cv2.imshow("RPI H264 60fps", frame) + if cv2.waitKey(1) == 27: break # Request data from the slave \ No newline at end of file From ebb85a93ebb1f2c7fb6ed32333aceb23eb8f5c66 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sun, 30 Nov 2025 06:12:14 +0100 Subject: [PATCH 067/107] changement du thread de camera_serv dans serveur_mq --- src/HL/Camera_serv.py | 35 +++++++++++++----------------- src/HL/Serveur_mq.py | 50 ++++++------------------------------------- 2 files changed, 22 insertions(+), 63 deletions(-) diff --git a/src/HL/Camera_serv.py b/src/HL/Camera_serv.py index cef31815..b06053a4 100644 --- a/src/HL/Camera_serv.py +++ b/src/HL/Camera_serv.py @@ -77,26 +77,21 @@ class StreamServer(socketserver.ThreadingMixIn, server.HTTPServer): # Thread principal de capture + serveur HTTP # ------------------------------------------------------------------- def start_camera_stream(port=8000, size=(640, 480)): - def run(): - picam2 = Picamera2() - picam2.configure(picam2.create_video_configuration( - main={"size": size} - )) - - output = StreamOutput() - picam2.start_recording(JpegEncoder(), FileOutput(output)) - - httpd = StreamServer(("", port), StreamHandler) - print(f"[INFO] Serveur MJPEG en ligne sur http://:{port}/stream.mjpg") - - try: - httpd.serve_forever() - finally: - picam2.stop_recording() - - t = threading.Thread(target=run, daemon=True) - t.start() - return t + picam2 = Picamera2() + picam2.configure(picam2.create_video_configuration( + main={"size": size} + )) + + output = StreamOutput() + picam2.start_recording(JpegEncoder(), FileOutput(output)) + + httpd = StreamServer(("", port), StreamHandler) + print(f"[INFO] Serveur MJPEG en ligne sur http://:{port}/stream.mjpg") + + try: + httpd.serve_forever() + finally: + picam2.stop_recording() # ------------------------------------------------------------------- diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 7f170926..5f77a270 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -345,48 +345,11 @@ def lidar_update_data(self): def _start_video_stream(self): """Start continuous JPEG compressed video streaming via ZMQ.""" - # context = zmq.Context() - # socket = context.socket(zmq.PUSH) - # socket.bind("tcp://0.0.0.0:6001") # port dédié au flux vidéo - - from io import BytesIO - cmd = [ - "rpicam-vid", - "-t", "0", - "--width", "640", - "--height", "480", - "--framerate", "30", - "--codec", "h264", - "--inline", - "--libav-format", "mpegts", - "-o", "tcp://0.0.0.0:6002?listen" - ] - cam = None - while True: - try: - if cam is None or cam.poll() is not None: - print("[Video] Starting rpicam-vid service...") - cam = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=os.setsid - ) - - # log output - for line in cam.stdout: - print("[rpicam-vid]", line.decode().strip()) - time.sleep(1) - # frame = self.camera.capture_image() # PIL image - # buffer = BytesIO() - # frame.save(buffer, format="JPEG", quality=70) - # jpg_bytes = buffer.getvalue() - # socket.send(jpg_bytes) # direct bytes (pas de JSON) - # time.sleep(0.03) # ~30 fps max, selon Pi - except Exception as e: - log.error(f"Video stream error: {e}") - time.sleep(1) - + try: + start_camera_stream(port=8000) + except: + print("Camera Down...") + #--------------------------------------------------------------------------------------------------- # Processus #--------------------------------------------------------------------------------------------------- @@ -465,7 +428,8 @@ def main(self): threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() - start_camera_stream(port=8000) + threading.Thread(target=self._start_video_stream, daemon=True).start() + while True: self.Idle() From 8606da1fe50201d13c4d81a880ec9d54a79e6bd4 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Sun, 30 Nov 2025 06:26:10 +0100 Subject: [PATCH 068/107] =?UTF-8?q?modification=20pour=20que=20Camera=20ut?= =?UTF-8?q?ilise=20Camera=5Fserv=20pour=20r=C3=A9cup=C3=A9r=C3=A9=20les=20?= =?UTF-8?q?information?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Camera.py | 36 ++++++++++++++++++------------------ src/HL/Serveur_mq.py | 8 ++++---- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/HL/Camera.py b/src/HL/Camera.py index 011c8dc5..77e23276 100644 --- a/src/HL/Camera.py +++ b/src/HL/Camera.py @@ -8,7 +8,7 @@ import shutil import scipy as sp import time - +from camera_server import get_current_frame, start_camera_stream N_IMAGES = 100 # Number of images to capture SAVE_DIR = "Captured_Frames" # Directory to save frames DEBUG_DIR = "Debug" # Directory for debug images @@ -22,36 +22,36 @@ Y_OFFSET = -80 # Offset for the y-axis in the image class Camera: - def __init__(self, url="tcp://192.168.1.10:6002"): + def __init__(self): os.environ["LIBCAMERA_LOG_LEVELS"] = "WARN" self.debug_counter = 0 # Counter for debug images self.image_no = 0 self.image_path = None - self.url = url.replace("tcp://", "") - self.url = f"tcp://{self.url}" - self.cap = cv2.VideoCapture(self.url, cv2.CAP_FFMPEG) - - if not self.cap.isOpened(): - raise RuntimeError(f"Impossible d'ouvrir le flux vidéo : {self.url}") - self.last_frame = None self.flag_stop = False self.thread = None # Stocke le thread pour contrôle ultérieur + camlogger = log.getLogger("picamera2") camlogger.setLevel(log.INFO) + os.makedirs(SAVE_DIR, exist_ok=True) # Crée le répertoire s'il n'existe pas os.makedirs(DEBUG_DIR, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas os.makedirs(DEBUG_DIR_wayfinding, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas + self.capture_image() # Capture une image pour initialiser le répertoire de sauvegarde def capture_image(self): - ok, frame = self.cap.read() + jpeg = get_current_frame() - if not ok: + if jpeg is None: time.sleep(0.01) - return self.last_frame # fallback si frame ratée - + return self.last_frame + + np_frame = cv2.imdecode(np.frombuffer(jpeg, dtype=np.uint8), cv2.IMREAD_COLOR) + if np_frame is None: + return self.last_frame + frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) self.last_frame = frame @@ -90,11 +90,10 @@ def stop(self): shutil.rmtree(SAVE_DIR) # Supprime le répertoire des images capturées def get_last_image(self): - last_image_no= self.image_no - 1 if self.image_no > 0 else 99 # - image_path = os.path.join(SAVE_DIR, f"frame_{last_image_no:02d}.jpg") - image= Image.open(image_path).convert("RGB") - image_np = np.array(image) - return image_np + last_no = self.image_no - 1 if self.image_no > 0 else 99 + path = os.path.join(SAVE_DIR, f"frame_{last_no:02d}.jpg") + image = Image.open(path).convert("RGB") + return np.array(image) def camera_matrix(self, vector_size=128, image=None): """ @@ -226,6 +225,7 @@ def is_running_in_reversed(self, image = None, LEFT_IS_GREEN=True): if __name__ == "__main__": log.basicConfig(level=log.DEBUG) + start_camera_stream() image_path = "src\HL\wrong_direction33.jpg" # Replace with your image path camera = Camera() camera.start() diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 5f77a270..17628ec9 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -21,9 +21,9 @@ from get_ip import get_ip, check_ssh_connections import subprocess from Lidar import Lidar -from Camera import Camera +from Camera import Camera, start_camera_stream from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET -from camera_server import start_camera_stream, get_current_frame + serial = i2c(port=1, address=0x3C) device = ssd1306(serial) @@ -148,7 +148,7 @@ def __init__(self): self.Screen = 0 self.State = 0 self.scroll_offset = 3 - #self.camera = Camera() + self.camera = Camera() #----------------------------------------------------------------------------------------------------- # affichage de l'écrans @@ -429,7 +429,7 @@ def main(self): threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() threading.Thread(target=self._start_video_stream, daemon=True).start() - + while True: self.Idle() From 459e5e033f83b0d469333a20578cc3d3a8b60084 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Mon, 1 Dec 2025 23:53:32 +0100 Subject: [PATCH 069/107] changement en uv sync et rajout de opencv dans les dependance --- pyproject.toml | 1 + scripts/startup.sh | 1 - src/HL/Serveur_mq.py | 2 +- uv.lock | 144 +++++++++---------------------------------- 4 files changed, 31 insertions(+), 117 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6eab4db4..63789785 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,4 +59,5 @@ rpi = [ "zmq>=0.0.0", "netifaces>=0.11.0", "matplotlib>=3.10.5", + "opencv-python>=4.12.0.88", ] diff --git a/scripts/startup.sh b/scripts/startup.sh index 0df29d1d..0f798a2c 100755 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -16,6 +16,5 @@ cd /home/intech/CoVAPSy # Pull the latest changes from the repository git pull -uv sync uv sync --extra rpi uv run /home/intech/CoVAPSy/src/HL/Serveur_mq.py diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 17628ec9..c2c5a7d4 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -254,6 +254,7 @@ def _initialize_camera(self): #--------------------------------------------------------------------------------------------------- def i2c_loop(self): """Envoie vitesse/direction régulièrement au microcontroleur.""" + print("lancement de l'i2c") while True: try : @@ -296,7 +297,6 @@ def car_controle(self,socket, is_private): data, ip = socket.recvfrom(1024) self.vitesse_d, self.direction = struct.unpack("ff", data) self.last_cmd_time = time.time() - print(ip) def envoie_donnee(self, socket): """ on regarde si il s'agit de lappelle pour le control interne diff --git a/uv.lock b/uv.lock index d39db1ce..46a915a0 100644 --- a/uv.lock +++ b/uv.lock @@ -159,6 +159,7 @@ rpi = [ { name = "matplotlib" }, { name = "netifaces" }, { name = "onnxruntime" }, + { name = "opencv-python" }, { name = "pyps4controller" }, { name = "rpi-gpio" }, { name = "rpi-hardware-pwm" }, @@ -168,8 +169,7 @@ rpi = [ ] simu = [ { name = "matplotlib" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "onnx" }, { name = "onnxruntime" }, { name = "stable-baselines3" }, @@ -195,6 +195,7 @@ requires-dist = [ { name = "onnx", marker = "extra == 'simu'", specifier = ">=1.8.0" }, { name = "onnxruntime", marker = "extra == 'rpi'", specifier = ">=1.8.0" }, { name = "onnxruntime", marker = "extra == 'simu'", specifier = ">=1.8.0" }, + { name = "opencv-python", marker = "extra == 'rpi'", specifier = ">=4.12.0.88" }, { name = "pyps4controller", marker = "extra == 'rpi'", specifier = ">=1.2.0" }, { name = "rpi-gpio", marker = "extra == 'rpi'", specifier = ">=0.7.1" }, { name = "rpi-hardware-pwm", marker = "extra == 'rpi'", specifier = ">=0.1.0" }, @@ -508,7 +509,7 @@ resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -586,7 +587,7 @@ resolution-markers = [ "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -829,8 +830,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cloudpickle" }, { name = "farama-notifications" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fd/17/c2a0e15c2cd5a8e788389b280996db927b923410de676ec5c7b2695e9261/gymnasium-1.2.0.tar.gz", hash = "sha256:344e87561012558f603880baf264ebc97f8a5c997a957b0c9f910281145534b0", size = 821142, upload-time = "2025-06-27T08:21:20.262Z" } @@ -1095,8 +1095,7 @@ dependencies = [ { name = "cycler" }, { name = "fonttools" }, { name = "kiwisolver" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pillow" }, { name = "pyparsing" }, @@ -1256,8 +1255,7 @@ name = "ml-dtypes" version = "0.5.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/78/a7/aad060393123cfb383956dca68402aff3db1e1caffd5764887ed5153f41b/ml_dtypes-0.5.3.tar.gz", hash = "sha256:95ce33057ba4d05df50b1f3cfefab22e351868a843b3b15a46c65836283670c9", size = 692316, upload-time = "2025-07-29T18:39:19.454Z" } wheels = [ @@ -1346,11 +1344,6 @@ wheels = [ name = "numpy" version = "2.2.6" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", -] sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, @@ -1409,98 +1402,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, ] -[[package]] -name = "numpy" -version = "2.3.2" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", -] -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/3fec4199c5ffb892bed55cff901e4f39a58c81df9c44c280499e92cad264/numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48", size = 20489306, upload-time = "2025-07-24T21:32:07.553Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/96/26/1320083986108998bd487e2931eed2aeedf914b6e8905431487543ec911d/numpy-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9", size = 21259016, upload-time = "2025-07-24T20:24:35.214Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2b/792b341463fa93fc7e55abbdbe87dac316c5b8cb5e94fb7a59fb6fa0cda5/numpy-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168", size = 14451158, upload-time = "2025-07-24T20:24:58.397Z" }, - { url = "https://files.pythonhosted.org/packages/b7/13/e792d7209261afb0c9f4759ffef6135b35c77c6349a151f488f531d13595/numpy-2.3.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b", size = 5379817, upload-time = "2025-07-24T20:25:07.746Z" }, - { url = "https://files.pythonhosted.org/packages/49/ce/055274fcba4107c022b2113a213c7287346563f48d62e8d2a5176ad93217/numpy-2.3.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8", size = 6913606, upload-time = "2025-07-24T20:25:18.84Z" }, - { url = "https://files.pythonhosted.org/packages/17/f2/e4d72e6bc5ff01e2ab613dc198d560714971900c03674b41947e38606502/numpy-2.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d", size = 14589652, upload-time = "2025-07-24T20:25:40.356Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b0/fbeee3000a51ebf7222016e2939b5c5ecf8000a19555d04a18f1e02521b8/numpy-2.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3", size = 16938816, upload-time = "2025-07-24T20:26:05.721Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ec/2f6c45c3484cc159621ea8fc000ac5a86f1575f090cac78ac27193ce82cd/numpy-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f", size = 16370512, upload-time = "2025-07-24T20:26:30.545Z" }, - { url = "https://files.pythonhosted.org/packages/b5/01/dd67cf511850bd7aefd6347aaae0956ed415abea741ae107834aae7d6d4e/numpy-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097", size = 18884947, upload-time = "2025-07-24T20:26:58.24Z" }, - { url = "https://files.pythonhosted.org/packages/a7/17/2cf60fd3e6a61d006778735edf67a222787a8c1a7842aed43ef96d777446/numpy-2.3.2-cp311-cp311-win32.whl", hash = "sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220", size = 6599494, upload-time = "2025-07-24T20:27:09.786Z" }, - { url = "https://files.pythonhosted.org/packages/d5/03/0eade211c504bda872a594f045f98ddcc6caef2b7c63610946845e304d3f/numpy-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170", size = 13087889, upload-time = "2025-07-24T20:27:29.558Z" }, - { url = "https://files.pythonhosted.org/packages/13/32/2c7979d39dafb2a25087e12310fc7f3b9d3c7d960df4f4bc97955ae0ce1d/numpy-2.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89", size = 10459560, upload-time = "2025-07-24T20:27:46.803Z" }, - { url = "https://files.pythonhosted.org/packages/00/6d/745dd1c1c5c284d17725e5c802ca4d45cfc6803519d777f087b71c9f4069/numpy-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b", size = 20956420, upload-time = "2025-07-24T20:28:18.002Z" }, - { url = "https://files.pythonhosted.org/packages/bc/96/e7b533ea5740641dd62b07a790af5d9d8fec36000b8e2d0472bd7574105f/numpy-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f", size = 14184660, upload-time = "2025-07-24T20:28:39.522Z" }, - { url = "https://files.pythonhosted.org/packages/2b/53/102c6122db45a62aa20d1b18c9986f67e6b97e0d6fbc1ae13e3e4c84430c/numpy-2.3.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0", size = 5113382, upload-time = "2025-07-24T20:28:48.544Z" }, - { url = "https://files.pythonhosted.org/packages/2b/21/376257efcbf63e624250717e82b4fae93d60178f09eb03ed766dbb48ec9c/numpy-2.3.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b", size = 6647258, upload-time = "2025-07-24T20:28:59.104Z" }, - { url = "https://files.pythonhosted.org/packages/91/ba/f4ebf257f08affa464fe6036e13f2bf9d4642a40228781dc1235da81be9f/numpy-2.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370", size = 14281409, upload-time = "2025-07-24T20:40:30.298Z" }, - { url = "https://files.pythonhosted.org/packages/59/ef/f96536f1df42c668cbacb727a8c6da7afc9c05ece6d558927fb1722693e1/numpy-2.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73", size = 16641317, upload-time = "2025-07-24T20:40:56.625Z" }, - { url = "https://files.pythonhosted.org/packages/f6/a7/af813a7b4f9a42f498dde8a4c6fcbff8100eed00182cc91dbaf095645f38/numpy-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc", size = 16056262, upload-time = "2025-07-24T20:41:20.797Z" }, - { url = "https://files.pythonhosted.org/packages/8b/5d/41c4ef8404caaa7f05ed1cfb06afe16a25895260eacbd29b4d84dff2920b/numpy-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be", size = 18579342, upload-time = "2025-07-24T20:41:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4f/9950e44c5a11636f4a3af6e825ec23003475cc9a466edb7a759ed3ea63bd/numpy-2.3.2-cp312-cp312-win32.whl", hash = "sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036", size = 6320610, upload-time = "2025-07-24T20:42:01.551Z" }, - { url = "https://files.pythonhosted.org/packages/7c/2f/244643a5ce54a94f0a9a2ab578189c061e4a87c002e037b0829dd77293b6/numpy-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f", size = 12786292, upload-time = "2025-07-24T20:42:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/54/cd/7b5f49d5d78db7badab22d8323c1b6ae458fbf86c4fdfa194ab3cd4eb39b/numpy-2.3.2-cp312-cp312-win_arm64.whl", hash = "sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07", size = 10194071, upload-time = "2025-07-24T20:42:36.657Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c0/c6bb172c916b00700ed3bf71cb56175fd1f7dbecebf8353545d0b5519f6c/numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3", size = 20949074, upload-time = "2025-07-24T20:43:07.813Z" }, - { url = "https://files.pythonhosted.org/packages/20/4e/c116466d22acaf4573e58421c956c6076dc526e24a6be0903219775d862e/numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b", size = 14177311, upload-time = "2025-07-24T20:43:29.335Z" }, - { url = "https://files.pythonhosted.org/packages/78/45/d4698c182895af189c463fc91d70805d455a227261d950e4e0f1310c2550/numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6", size = 5106022, upload-time = "2025-07-24T20:43:37.999Z" }, - { url = "https://files.pythonhosted.org/packages/9f/76/3e6880fef4420179309dba72a8c11f6166c431cf6dee54c577af8906f914/numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089", size = 6640135, upload-time = "2025-07-24T20:43:49.28Z" }, - { url = "https://files.pythonhosted.org/packages/34/fa/87ff7f25b3c4ce9085a62554460b7db686fef1e0207e8977795c7b7d7ba1/numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2", size = 14278147, upload-time = "2025-07-24T20:44:10.328Z" }, - { url = "https://files.pythonhosted.org/packages/1d/0f/571b2c7a3833ae419fe69ff7b479a78d313581785203cc70a8db90121b9a/numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f", size = 16635989, upload-time = "2025-07-24T20:44:34.88Z" }, - { url = "https://files.pythonhosted.org/packages/24/5a/84ae8dca9c9a4c592fe11340b36a86ffa9fd3e40513198daf8a97839345c/numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee", size = 16053052, upload-time = "2025-07-24T20:44:58.872Z" }, - { url = "https://files.pythonhosted.org/packages/57/7c/e5725d99a9133b9813fcf148d3f858df98511686e853169dbaf63aec6097/numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6", size = 18577955, upload-time = "2025-07-24T20:45:26.714Z" }, - { url = "https://files.pythonhosted.org/packages/ae/11/7c546fcf42145f29b71e4d6f429e96d8d68e5a7ba1830b2e68d7418f0bbd/numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b", size = 6311843, upload-time = "2025-07-24T20:49:24.444Z" }, - { url = "https://files.pythonhosted.org/packages/aa/6f/a428fd1cb7ed39b4280d057720fed5121b0d7754fd2a9768640160f5517b/numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56", size = 12782876, upload-time = "2025-07-24T20:49:43.227Z" }, - { url = "https://files.pythonhosted.org/packages/65/85/4ea455c9040a12595fb6c43f2c217257c7b52dd0ba332c6a6c1d28b289fe/numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2", size = 10192786, upload-time = "2025-07-24T20:49:59.443Z" }, - { url = "https://files.pythonhosted.org/packages/80/23/8278f40282d10c3f258ec3ff1b103d4994bcad78b0cba9208317f6bb73da/numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab", size = 21047395, upload-time = "2025-07-24T20:45:58.821Z" }, - { url = "https://files.pythonhosted.org/packages/1f/2d/624f2ce4a5df52628b4ccd16a4f9437b37c35f4f8a50d00e962aae6efd7a/numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2", size = 14300374, upload-time = "2025-07-24T20:46:20.207Z" }, - { url = "https://files.pythonhosted.org/packages/f6/62/ff1e512cdbb829b80a6bd08318a58698867bca0ca2499d101b4af063ee97/numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a", size = 5228864, upload-time = "2025-07-24T20:46:30.58Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8e/74bc18078fff03192d4032cfa99d5a5ca937807136d6f5790ce07ca53515/numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286", size = 6737533, upload-time = "2025-07-24T20:46:46.111Z" }, - { url = "https://files.pythonhosted.org/packages/19/ea/0731efe2c9073ccca5698ef6a8c3667c4cf4eea53fcdcd0b50140aba03bc/numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8", size = 14352007, upload-time = "2025-07-24T20:47:07.1Z" }, - { url = "https://files.pythonhosted.org/packages/cf/90/36be0865f16dfed20f4bc7f75235b963d5939707d4b591f086777412ff7b/numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a", size = 16701914, upload-time = "2025-07-24T20:47:32.459Z" }, - { url = "https://files.pythonhosted.org/packages/94/30/06cd055e24cb6c38e5989a9e747042b4e723535758e6153f11afea88c01b/numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91", size = 16132708, upload-time = "2025-07-24T20:47:58.129Z" }, - { url = "https://files.pythonhosted.org/packages/9a/14/ecede608ea73e58267fd7cb78f42341b3b37ba576e778a1a06baffbe585c/numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5", size = 18651678, upload-time = "2025-07-24T20:48:25.402Z" }, - { url = "https://files.pythonhosted.org/packages/40/f3/2fe6066b8d07c3685509bc24d56386534c008b462a488b7f503ba82b8923/numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5", size = 6441832, upload-time = "2025-07-24T20:48:37.181Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ba/0937d66d05204d8f28630c9c60bc3eda68824abde4cf756c4d6aad03b0c6/numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450", size = 12927049, upload-time = "2025-07-24T20:48:56.24Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ed/13542dd59c104d5e654dfa2ac282c199ba64846a74c2c4bcdbc3a0f75df1/numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a", size = 10262935, upload-time = "2025-07-24T20:49:13.136Z" }, - { url = "https://files.pythonhosted.org/packages/c9/7c/7659048aaf498f7611b783e000c7268fcc4dcf0ce21cd10aad7b2e8f9591/numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a", size = 20950906, upload-time = "2025-07-24T20:50:30.346Z" }, - { url = "https://files.pythonhosted.org/packages/80/db/984bea9d4ddf7112a04cfdfb22b1050af5757864cfffe8e09e44b7f11a10/numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b", size = 14185607, upload-time = "2025-07-24T20:50:51.923Z" }, - { url = "https://files.pythonhosted.org/packages/e4/76/b3d6f414f4eca568f469ac112a3b510938d892bc5a6c190cb883af080b77/numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125", size = 5114110, upload-time = "2025-07-24T20:51:01.041Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d2/6f5e6826abd6bca52392ed88fe44a4b52aacb60567ac3bc86c67834c3a56/numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19", size = 6642050, upload-time = "2025-07-24T20:51:11.64Z" }, - { url = "https://files.pythonhosted.org/packages/c4/43/f12b2ade99199e39c73ad182f103f9d9791f48d885c600c8e05927865baf/numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f", size = 14296292, upload-time = "2025-07-24T20:51:33.488Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f9/77c07d94bf110a916b17210fac38680ed8734c236bfed9982fd8524a7b47/numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", size = 16638913, upload-time = "2025-07-24T20:51:58.517Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d1/9d9f2c8ea399cc05cfff8a7437453bd4e7d894373a93cdc46361bbb49a7d/numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58", size = 16071180, upload-time = "2025-07-24T20:52:22.827Z" }, - { url = "https://files.pythonhosted.org/packages/4c/41/82e2c68aff2a0c9bf315e47d61951099fed65d8cb2c8d9dc388cb87e947e/numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0", size = 18576809, upload-time = "2025-07-24T20:52:51.015Z" }, - { url = "https://files.pythonhosted.org/packages/14/14/4b4fd3efb0837ed252d0f583c5c35a75121038a8c4e065f2c259be06d2d8/numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2", size = 6366410, upload-time = "2025-07-24T20:56:44.949Z" }, - { url = "https://files.pythonhosted.org/packages/11/9e/b4c24a6b8467b61aced5c8dc7dcfce23621baa2e17f661edb2444a418040/numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b", size = 12918821, upload-time = "2025-07-24T20:57:06.479Z" }, - { url = "https://files.pythonhosted.org/packages/0e/0f/0dc44007c70b1007c1cef86b06986a3812dd7106d8f946c09cfa75782556/numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910", size = 10477303, upload-time = "2025-07-24T20:57:22.879Z" }, - { url = "https://files.pythonhosted.org/packages/8b/3e/075752b79140b78ddfc9c0a1634d234cfdbc6f9bbbfa6b7504e445ad7d19/numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e", size = 21047524, upload-time = "2025-07-24T20:53:22.086Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6d/60e8247564a72426570d0e0ea1151b95ce5bd2f1597bb878a18d32aec855/numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45", size = 14300519, upload-time = "2025-07-24T20:53:44.053Z" }, - { url = "https://files.pythonhosted.org/packages/4d/73/d8326c442cd428d47a067070c3ac6cc3b651a6e53613a1668342a12d4479/numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b", size = 5228972, upload-time = "2025-07-24T20:53:53.81Z" }, - { url = "https://files.pythonhosted.org/packages/34/2e/e71b2d6dad075271e7079db776196829019b90ce3ece5c69639e4f6fdc44/numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2", size = 6737439, upload-time = "2025-07-24T20:54:04.742Z" }, - { url = "https://files.pythonhosted.org/packages/15/b0/d004bcd56c2c5e0500ffc65385eb6d569ffd3363cb5e593ae742749b2daa/numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0", size = 14352479, upload-time = "2025-07-24T20:54:25.819Z" }, - { url = "https://files.pythonhosted.org/packages/11/e3/285142fcff8721e0c99b51686426165059874c150ea9ab898e12a492e291/numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0", size = 16702805, upload-time = "2025-07-24T20:54:50.814Z" }, - { url = "https://files.pythonhosted.org/packages/33/c3/33b56b0e47e604af2c7cd065edca892d180f5899599b76830652875249a3/numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2", size = 16133830, upload-time = "2025-07-24T20:55:17.306Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ae/7b1476a1f4d6a48bc669b8deb09939c56dd2a439db1ab03017844374fb67/numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf", size = 18652665, upload-time = "2025-07-24T20:55:46.665Z" }, - { url = "https://files.pythonhosted.org/packages/14/ba/5b5c9978c4bb161034148ade2de9db44ec316fab89ce8c400db0e0c81f86/numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1", size = 6514777, upload-time = "2025-07-24T20:55:57.66Z" }, - { url = "https://files.pythonhosted.org/packages/eb/46/3dbaf0ae7c17cdc46b9f662c56da2054887b8d9e737c1476f335c83d33db/numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b", size = 13111856, upload-time = "2025-07-24T20:56:17.318Z" }, - { url = "https://files.pythonhosted.org/packages/c1/9e/1652778bce745a67b5fe05adde60ed362d38eb17d919a540e813d30f6874/numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631", size = 10544226, upload-time = "2025-07-24T20:56:34.509Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ea/50ebc91d28b275b23b7128ef25c3d08152bc4068f42742867e07a870a42a/numpy-2.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15", size = 21130338, upload-time = "2025-07-24T20:57:54.37Z" }, - { url = "https://files.pythonhosted.org/packages/9f/57/cdd5eac00dd5f137277355c318a955c0d8fb8aa486020c22afd305f8b88f/numpy-2.3.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec", size = 14375776, upload-time = "2025-07-24T20:58:16.303Z" }, - { url = "https://files.pythonhosted.org/packages/83/85/27280c7f34fcd305c2209c0cdca4d70775e4859a9eaa92f850087f8dea50/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712", size = 5304882, upload-time = "2025-07-24T20:58:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/48/b4/6500b24d278e15dd796f43824e69939d00981d37d9779e32499e823aa0aa/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c", size = 6818405, upload-time = "2025-07-24T20:58:37.341Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c9/142c1e03f199d202da8e980c2496213509291b6024fd2735ad28ae7065c7/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296", size = 14419651, upload-time = "2025-07-24T20:58:59.048Z" }, - { url = "https://files.pythonhosted.org/packages/8b/95/8023e87cbea31a750a6c00ff9427d65ebc5fef104a136bfa69f76266d614/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981", size = 16760166, upload-time = "2025-07-24T21:28:56.38Z" }, - { url = "https://files.pythonhosted.org/packages/78/e3/6690b3f85a05506733c7e90b577e4762517404ea78bab2ca3a5cb1aeb78d/numpy-2.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619", size = 12977811, upload-time = "2025-07-24T21:29:18.234Z" }, -] - [[package]] name = "nvidia-cublas-cu12" version = "12.8.4.1" @@ -1633,8 +1534,7 @@ version = "1.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ml-dtypes" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "protobuf" }, { name = "typing-extensions" }, ] @@ -1677,8 +1577,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coloredlogs" }, { name = "flatbuffers" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "protobuf" }, { name = "sympy" }, @@ -1704,6 +1603,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/15/d75fd66aba116ce3732bb1050401394c5ec52074c4f7ee18db8838dd4667/onnxruntime-1.22.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7e823624b015ea879d976cbef8bfaed2f7e2cc233d7506860a76dd37f8f381", size = 16477261, upload-time = "2025-07-10T19:16:03.226Z" }, ] +[[package]] +name = "opencv-python" +version = "4.12.0.88" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/71/25c98e634b6bdeca4727c7f6d6927b056080668c5008ad3c8fc9e7f8f6ec/opencv-python-4.12.0.88.tar.gz", hash = "sha256:8b738389cede219405f6f3880b851efa3415ccd674752219377353f017d2994d", size = 95373294, upload-time = "2025-07-07T09:20:52.389Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/68/3da40142e7c21e9b1d4e7ddd6c58738feb013203e6e4b803d62cdd9eb96b/opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:f9a1f08883257b95a5764bf517a32d75aec325319c8ed0f89739a57fae9e92a5", size = 37877727, upload-time = "2025-07-07T09:13:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/33/7c/042abe49f58d6ee7e1028eefc3334d98ca69b030e3b567fe245a2b28ea6f/opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:812eb116ad2b4de43ee116fcd8991c3a687f099ada0b04e68f64899c09448e81", size = 57326471, upload-time = "2025-07-07T09:13:41.26Z" }, + { url = "https://files.pythonhosted.org/packages/62/3a/440bd64736cf8116f01f3b7f9f2e111afb2e02beb2ccc08a6458114a6b5d/opencv_python-4.12.0.88-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:51fd981c7df6af3e8f70b1556696b05224c4e6b6777bdd2a46b3d4fb09de1a92", size = 45887139, upload-time = "2025-07-07T09:13:50.761Z" }, + { url = "https://files.pythonhosted.org/packages/68/1f/795e7f4aa2eacc59afa4fb61a2e35e510d06414dd5a802b51a012d691b37/opencv_python-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:092c16da4c5a163a818f120c22c5e4a2f96e0db4f24e659c701f1fe629a690f9", size = 67041680, upload-time = "2025-07-07T09:14:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/02/96/213fea371d3cb2f1d537612a105792aa0a6659fb2665b22cad709a75bd94/opencv_python-4.12.0.88-cp37-abi3-win32.whl", hash = "sha256:ff554d3f725b39878ac6a2e1fa232ec509c36130927afc18a1719ebf4fbf4357", size = 30284131, upload-time = "2025-07-07T09:14:08.819Z" }, + { url = "https://files.pythonhosted.org/packages/fa/80/eb88edc2e2b11cd2dd2e56f1c80b5784d11d6e6b7f04a1145df64df40065/opencv_python-4.12.0.88-cp37-abi3-win_amd64.whl", hash = "sha256:d98edb20aa932fd8ebd276a72627dad9dc097695b3d435a4257557bbb49a79d2", size = 39000307, upload-time = "2025-07-07T09:14:16.641Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -1718,8 +1634,7 @@ name = "pandas" version = "2.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -2223,8 +2138,7 @@ dependencies = [ { name = "cloudpickle" }, { name = "gymnasium" }, { name = "matplotlib" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "pandas" }, { name = "torch" }, ] From 5b6d3ff1f082a668bee29f3cf74825372eeca592 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Mon, 1 Dec 2025 23:59:07 +0100 Subject: [PATCH 070/107] rajouut de scipy en temps que dependance --- pyproject.toml | 1 + uv.lock | 146 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 63789785..71bcb76b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,4 +60,5 @@ rpi = [ "netifaces>=0.11.0", "matplotlib>=3.10.5", "opencv-python>=4.12.0.88", + "scipy>=1.15.3", ] diff --git a/uv.lock b/uv.lock index 46a915a0..a0d1ece2 100644 --- a/uv.lock +++ b/uv.lock @@ -163,6 +163,8 @@ rpi = [ { name = "pyps4controller" }, { name = "rpi-gpio" }, { name = "rpi-hardware-pwm" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.16.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "smbus" }, { name = "spidev" }, { name = "zmq" }, @@ -199,6 +201,7 @@ requires-dist = [ { name = "pyps4controller", marker = "extra == 'rpi'", specifier = ">=1.2.0" }, { name = "rpi-gpio", marker = "extra == 'rpi'", specifier = ">=0.7.1" }, { name = "rpi-hardware-pwm", marker = "extra == 'rpi'", specifier = ">=0.1.0" }, + { name = "scipy", marker = "extra == 'rpi'", specifier = ">=1.15.3" }, { name = "smbus", marker = "extra == 'rpi'", specifier = ">=1.1.post2" }, { name = "spidev", marker = "extra == 'rpi'", specifier = ">=3.5" }, { name = "stable-baselines3", marker = "extra == 'simu'", specifier = ">=1.6.0" }, @@ -2073,6 +2076,149 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4c/44/c417f283a4ccdb214cc26583e9d54640ba6f2cea2a561355ca4829e885bb/rpi_hardware_pwm-0.3.0-py3-none-any.whl", hash = "sha256:9a1407512871232c64c55572c1bcd0a0c2872a4241df53b79ca3b5e185499ee5", size = 4772, upload-time = "2025-05-23T14:50:44.538Z" }, ] +[[package]] +name = "scipy" +version = "1.15.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", +] +dependencies = [ + { name = "numpy", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, + { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload-time = "2025-05-08T16:05:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload-time = "2025-05-08T16:05:20.152Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload-time = "2025-05-08T16:05:24.494Z" }, + { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload-time = "2025-05-08T16:05:29.313Z" }, + { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload-time = "2025-05-08T16:05:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload-time = "2025-05-08T16:05:40.762Z" }, + { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload-time = "2025-05-08T16:05:48.119Z" }, + { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload-time = "2025-05-08T16:05:54.22Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload-time = "2025-05-08T16:06:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/37/4b/683aa044c4162e10ed7a7ea30527f2cbd92e6999c10a8ed8edb253836e9c/scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019", size = 38766735, upload-time = "2025-05-08T16:06:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7e/f30be3d03de07f25dc0ec926d1681fed5c732d759ac8f51079708c79e680/scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6", size = 30173284, upload-time = "2025-05-08T16:06:11.686Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/0ddb0d0abdabe0d181c1793db51f02cd59e4901da6f9f7848e1f96759f0d/scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477", size = 22446958, upload-time = "2025-05-08T16:06:15.97Z" }, + { url = "https://files.pythonhosted.org/packages/af/43/0bce905a965f36c58ff80d8bea33f1f9351b05fad4beaad4eae34699b7a1/scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c", size = 25242454, upload-time = "2025-05-08T16:06:20.394Z" }, + { url = "https://files.pythonhosted.org/packages/56/30/a6f08f84ee5b7b28b4c597aca4cbe545535c39fe911845a96414700b64ba/scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45", size = 35210199, upload-time = "2025-05-08T16:06:26.159Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1f/03f52c282437a168ee2c7c14a1a0d0781a9a4a8962d84ac05c06b4c5b555/scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49", size = 37309455, upload-time = "2025-05-08T16:06:32.778Z" }, + { url = "https://files.pythonhosted.org/packages/89/b1/fbb53137f42c4bf630b1ffdfc2151a62d1d1b903b249f030d2b1c0280af8/scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e", size = 36885140, upload-time = "2025-05-08T16:06:39.249Z" }, + { url = "https://files.pythonhosted.org/packages/2e/2e/025e39e339f5090df1ff266d021892694dbb7e63568edcfe43f892fa381d/scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539", size = 39710549, upload-time = "2025-05-08T16:06:45.729Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184, upload-time = "2025-05-08T16:06:52.623Z" }, + { url = "https://files.pythonhosted.org/packages/73/18/ec27848c9baae6e0d6573eda6e01a602e5649ee72c27c3a8aad673ebecfd/scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759", size = 38728256, upload-time = "2025-05-08T16:06:58.696Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/1aef2184948728b4b6e21267d53b3339762c285a46a274ebb7863c9e4742/scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62", size = 30109540, upload-time = "2025-05-08T16:07:04.209Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d8/59e452c0a255ec352bd0a833537a3bc1bfb679944c4938ab375b0a6b3a3e/scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb", size = 22383115, upload-time = "2025-05-08T16:07:08.998Z" }, + { url = "https://files.pythonhosted.org/packages/08/f5/456f56bbbfccf696263b47095291040655e3cbaf05d063bdc7c7517f32ac/scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730", size = 25163884, upload-time = "2025-05-08T16:07:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/a2/66/a9618b6a435a0f0c0b8a6d0a2efb32d4ec5a85f023c2b79d39512040355b/scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825", size = 35174018, upload-time = "2025-05-08T16:07:19.427Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7", size = 37269716, upload-time = "2025-05-08T16:07:25.712Z" }, + { url = "https://files.pythonhosted.org/packages/77/0a/eac00ff741f23bcabd352731ed9b8995a0a60ef57f5fd788d611d43d69a1/scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11", size = 36872342, upload-time = "2025-05-08T16:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/4379be86dd74b6ad81551689107360d9a3e18f24d20767a2d5b9253a3f0a/scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126", size = 39670869, upload-time = "2025-05-08T16:07:38.002Z" }, + { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851, upload-time = "2025-05-08T16:08:33.671Z" }, + { url = "https://files.pythonhosted.org/packages/1b/e9/7a879c137f7e55b30d75d90ce3eb468197646bc7b443ac036ae3fe109055/scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8", size = 38863011, upload-time = "2025-05-08T16:07:44.039Z" }, + { url = "https://files.pythonhosted.org/packages/51/d1/226a806bbd69f62ce5ef5f3ffadc35286e9fbc802f606a07eb83bf2359de/scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5", size = 30266407, upload-time = "2025-05-08T16:07:49.891Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9b/f32d1d6093ab9eeabbd839b0f7619c62e46cc4b7b6dbf05b6e615bbd4400/scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e", size = 22540030, upload-time = "2025-05-08T16:07:54.121Z" }, + { url = "https://files.pythonhosted.org/packages/e7/29/c278f699b095c1a884f29fda126340fcc201461ee8bfea5c8bdb1c7c958b/scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb", size = 25218709, upload-time = "2025-05-08T16:07:58.506Z" }, + { url = "https://files.pythonhosted.org/packages/24/18/9e5374b617aba742a990581373cd6b68a2945d65cc588482749ef2e64467/scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723", size = 34809045, upload-time = "2025-05-08T16:08:03.929Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fe/9c4361e7ba2927074360856db6135ef4904d505e9b3afbbcb073c4008328/scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb", size = 36703062, upload-time = "2025-05-08T16:08:09.558Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/038ccfe29d272b30086b25a4960f757f97122cb2ec42e62b460d02fe98e9/scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4", size = 36393132, upload-time = "2025-05-08T16:08:15.34Z" }, + { url = "https://files.pythonhosted.org/packages/10/7e/5c12285452970be5bdbe8352c619250b97ebf7917d7a9a9e96b8a8140f17/scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5", size = 38979503, upload-time = "2025-05-08T16:08:21.513Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097, upload-time = "2025-05-08T16:08:27.627Z" }, +] + +[[package]] +name = "scipy" +version = "1.16.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.13' and sys_platform == 'darwin'", + "python_full_version == '3.12.*' and sys_platform == 'darwin'", + "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", + "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", +] +dependencies = [ + { name = "numpy", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/ca/d8ace4f98322d01abcd52d381134344bf7b431eba7ed8b42bdea5a3c2ac9/scipy-1.16.3.tar.gz", hash = "sha256:01e87659402762f43bd2fee13370553a17ada367d42e7487800bf2916535aecb", size = 30597883, upload-time = "2025-10-28T17:38:54.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/5f/6f37d7439de1455ce9c5a556b8d1db0979f03a796c030bafdf08d35b7bf9/scipy-1.16.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:40be6cf99e68b6c4321e9f8782e7d5ff8265af28ef2cd56e9c9b2638fa08ad97", size = 36630881, upload-time = "2025-10-28T17:31:47.104Z" }, + { url = "https://files.pythonhosted.org/packages/7c/89/d70e9f628749b7e4db2aa4cd89735502ff3f08f7b9b27d2e799485987cd9/scipy-1.16.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:8be1ca9170fcb6223cc7c27f4305d680ded114a1567c0bd2bfcbf947d1b17511", size = 28941012, upload-time = "2025-10-28T17:31:53.411Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a8/0e7a9a6872a923505dbdf6bb93451edcac120363131c19013044a1e7cb0c/scipy-1.16.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bea0a62734d20d67608660f69dcda23e7f90fb4ca20974ab80b6ed40df87a005", size = 20931935, upload-time = "2025-10-28T17:31:57.361Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c7/020fb72bd79ad798e4dbe53938543ecb96b3a9ac3fe274b7189e23e27353/scipy-1.16.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:2a207a6ce9c24f1951241f4693ede2d393f59c07abc159b2cb2be980820e01fb", size = 23534466, upload-time = "2025-10-28T17:32:01.875Z" }, + { url = "https://files.pythonhosted.org/packages/be/a0/668c4609ce6dbf2f948e167836ccaf897f95fb63fa231c87da7558a374cd/scipy-1.16.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:532fb5ad6a87e9e9cd9c959b106b73145a03f04c7d57ea3e6f6bb60b86ab0876", size = 33593618, upload-time = "2025-10-28T17:32:06.902Z" }, + { url = "https://files.pythonhosted.org/packages/ca/6e/8942461cf2636cdae083e3eb72622a7fbbfa5cf559c7d13ab250a5dbdc01/scipy-1.16.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0151a0749efeaaab78711c78422d413c583b8cdd2011a3c1d6c794938ee9fdb2", size = 35899798, upload-time = "2025-10-28T17:32:12.665Z" }, + { url = "https://files.pythonhosted.org/packages/79/e8/d0f33590364cdbd67f28ce79368b373889faa4ee959588beddf6daef9abe/scipy-1.16.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7180967113560cca57418a7bc719e30366b47959dd845a93206fbed693c867e", size = 36226154, upload-time = "2025-10-28T17:32:17.961Z" }, + { url = "https://files.pythonhosted.org/packages/39/c1/1903de608c0c924a1749c590064e65810f8046e437aba6be365abc4f7557/scipy-1.16.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:deb3841c925eeddb6afc1e4e4a45e418d19ec7b87c5df177695224078e8ec733", size = 38878540, upload-time = "2025-10-28T17:32:23.907Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d0/22ec7036ba0b0a35bccb7f25ab407382ed34af0b111475eb301c16f8a2e5/scipy-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:53c3844d527213631e886621df5695d35e4f6a75f620dca412bcd292f6b87d78", size = 38722107, upload-time = "2025-10-28T17:32:29.921Z" }, + { url = "https://files.pythonhosted.org/packages/7b/60/8a00e5a524bb3bf8898db1650d350f50e6cffb9d7a491c561dc9826c7515/scipy-1.16.3-cp311-cp311-win_arm64.whl", hash = "sha256:9452781bd879b14b6f055b26643703551320aa8d79ae064a71df55c00286a184", size = 25506272, upload-time = "2025-10-28T17:32:34.577Z" }, + { url = "https://files.pythonhosted.org/packages/40/41/5bf55c3f386b1643812f3a5674edf74b26184378ef0f3e7c7a09a7e2ca7f/scipy-1.16.3-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81fc5827606858cf71446a5e98715ba0e11f0dbc83d71c7409d05486592a45d6", size = 36659043, upload-time = "2025-10-28T17:32:40.285Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0f/65582071948cfc45d43e9870bf7ca5f0e0684e165d7c9ef4e50d783073eb/scipy-1.16.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c97176013d404c7346bf57874eaac5187d969293bf40497140b0a2b2b7482e07", size = 28898986, upload-time = "2025-10-28T17:32:45.325Z" }, + { url = "https://files.pythonhosted.org/packages/96/5e/36bf3f0ac298187d1ceadde9051177d6a4fe4d507e8f59067dc9dd39e650/scipy-1.16.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2b71d93c8a9936046866acebc915e2af2e292b883ed6e2cbe5c34beb094b82d9", size = 20889814, upload-time = "2025-10-28T17:32:49.277Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/178d9d0c35394d5d5211bbff7ac4f2986c5488b59506fef9e1de13ea28d3/scipy-1.16.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3d4a07a8e785d80289dfe66b7c27d8634a773020742ec7187b85ccc4b0e7b686", size = 23565795, upload-time = "2025-10-28T17:32:53.337Z" }, + { url = "https://files.pythonhosted.org/packages/fa/46/d1146ff536d034d02f83c8afc3c4bab2eddb634624d6529a8512f3afc9da/scipy-1.16.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0553371015692a898e1aa858fed67a3576c34edefa6b7ebdb4e9dde49ce5c203", size = 33349476, upload-time = "2025-10-28T17:32:58.353Z" }, + { url = "https://files.pythonhosted.org/packages/79/2e/415119c9ab3e62249e18c2b082c07aff907a273741b3f8160414b0e9193c/scipy-1.16.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:72d1717fd3b5e6ec747327ce9bda32d5463f472c9dce9f54499e81fbd50245a1", size = 35676692, upload-time = "2025-10-28T17:33:03.88Z" }, + { url = "https://files.pythonhosted.org/packages/27/82/df26e44da78bf8d2aeaf7566082260cfa15955a5a6e96e6a29935b64132f/scipy-1.16.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fb2472e72e24d1530debe6ae078db70fb1605350c88a3d14bc401d6306dbffe", size = 36019345, upload-time = "2025-10-28T17:33:09.773Z" }, + { url = "https://files.pythonhosted.org/packages/82/31/006cbb4b648ba379a95c87262c2855cd0d09453e500937f78b30f02fa1cd/scipy-1.16.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c5192722cffe15f9329a3948c4b1db789fbb1f05c97899187dcf009b283aea70", size = 38678975, upload-time = "2025-10-28T17:33:15.809Z" }, + { url = "https://files.pythonhosted.org/packages/c2/7f/acbd28c97e990b421af7d6d6cd416358c9c293fc958b8529e0bd5d2a2a19/scipy-1.16.3-cp312-cp312-win_amd64.whl", hash = "sha256:56edc65510d1331dae01ef9b658d428e33ed48b4f77b1d51caf479a0253f96dc", size = 38555926, upload-time = "2025-10-28T17:33:21.388Z" }, + { url = "https://files.pythonhosted.org/packages/ce/69/c5c7807fd007dad4f48e0a5f2153038dc96e8725d3345b9ee31b2b7bed46/scipy-1.16.3-cp312-cp312-win_arm64.whl", hash = "sha256:a8a26c78ef223d3e30920ef759e25625a0ecdd0d60e5a8818b7513c3e5384cf2", size = 25463014, upload-time = "2025-10-28T17:33:25.975Z" }, + { url = "https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c", size = 36617856, upload-time = "2025-10-28T17:33:31.375Z" }, + { url = "https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d", size = 28874306, upload-time = "2025-10-28T17:33:36.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/65/3a9400efd0228a176e6ec3454b1fa998fbbb5a8defa1672c3f65706987db/scipy-1.16.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:5803c5fadd29de0cf27fa08ccbfe7a9e5d741bf63e4ab1085437266f12460ff9", size = 20865371, upload-time = "2025-10-28T17:33:42.094Z" }, + { url = "https://files.pythonhosted.org/packages/33/d7/eda09adf009a9fb81827194d4dd02d2e4bc752cef16737cc4ef065234031/scipy-1.16.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:b81c27fc41954319a943d43b20e07c40bdcd3ff7cf013f4fb86286faefe546c4", size = 23524877, upload-time = "2025-10-28T17:33:48.483Z" }, + { url = "https://files.pythonhosted.org/packages/7d/6b/3f911e1ebc364cb81320223a3422aab7d26c9c7973109a9cd0f27c64c6c0/scipy-1.16.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0c3b4dd3d9b08dbce0f3440032c52e9e2ab9f96ade2d3943313dfe51a7056959", size = 33342103, upload-time = "2025-10-28T17:33:56.495Z" }, + { url = "https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88", size = 35697297, upload-time = "2025-10-28T17:34:04.722Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6496dadbc80d8d896ff72511ecfe2316b50313bfc3ebf07a3f580f08bd8c/scipy-1.16.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:663b8d66a8748051c3ee9c96465fb417509315b99c71550fda2591d7dd634234", size = 36021756, upload-time = "2025-10-28T17:34:13.482Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bd/a8c7799e0136b987bda3e1b23d155bcb31aec68a4a472554df5f0937eef7/scipy-1.16.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eab43fae33a0c39006a88096cd7b4f4ef545ea0447d250d5ac18202d40b6611d", size = 38696566, upload-time = "2025-10-28T17:34:22.384Z" }, + { url = "https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl", hash = "sha256:062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304", size = 38529877, upload-time = "2025-10-28T17:35:51.076Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/9d9fbcaa1260a94f4bb5b64ba9213ceb5d03cd88841fe9fd1ffd47a45b73/scipy-1.16.3-cp313-cp313-win_arm64.whl", hash = "sha256:50a3dbf286dbc7d84f176f9a1574c705f277cb6565069f88f60db9eafdbe3ee2", size = 25455366, upload-time = "2025-10-28T17:35:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a3/9ec205bd49f42d45d77f1730dbad9ccf146244c1647605cf834b3a8c4f36/scipy-1.16.3-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:fb4b29f4cf8cc5a8d628bc8d8e26d12d7278cd1f219f22698a378c3d67db5e4b", size = 37027931, upload-time = "2025-10-28T17:34:31.451Z" }, + { url = "https://files.pythonhosted.org/packages/25/06/ca9fd1f3a4589cbd825b1447e5db3a8ebb969c1eaf22c8579bd286f51b6d/scipy-1.16.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:8d09d72dc92742988b0e7750bddb8060b0c7079606c0d24a8cc8e9c9c11f9079", size = 29400081, upload-time = "2025-10-28T17:34:39.087Z" }, + { url = "https://files.pythonhosted.org/packages/6a/56/933e68210d92657d93fb0e381683bc0e53a965048d7358ff5fbf9e6a1b17/scipy-1.16.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:03192a35e661470197556de24e7cb1330d84b35b94ead65c46ad6f16f6b28f2a", size = 21391244, upload-time = "2025-10-28T17:34:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7e/779845db03dc1418e215726329674b40576879b91814568757ff0014ad65/scipy-1.16.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:57d01cb6f85e34f0946b33caa66e892aae072b64b034183f3d87c4025802a119", size = 23929753, upload-time = "2025-10-28T17:34:51.793Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/f756cf8161d5365dcdef9e5f460ab226c068211030a175d2fc7f3f41ca64/scipy-1.16.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:96491a6a54e995f00a28a3c3badfff58fd093bf26cd5fb34a2188c8c756a3a2c", size = 33496912, upload-time = "2025-10-28T17:34:59.8Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/222b1e49a58668f23839ca1542a6322bb095ab8d6590d4f71723869a6c2c/scipy-1.16.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cd13e354df9938598af2be05822c323e97132d5e6306b83a3b4ee6724c6e522e", size = 35802371, upload-time = "2025-10-28T17:35:08.173Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8d/5964ef68bb31829bde27611f8c9deeac13764589fe74a75390242b64ca44/scipy-1.16.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63d3cdacb8a824a295191a723ee5e4ea7768ca5ca5f2838532d9f2e2b3ce2135", size = 36190477, upload-time = "2025-10-28T17:35:16.7Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f2/b31d75cb9b5fa4dd39a0a931ee9b33e7f6f36f23be5ef560bf72e0f92f32/scipy-1.16.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e7efa2681ea410b10dde31a52b18b0154d66f2485328830e45fdf183af5aefc6", size = 38796678, upload-time = "2025-10-28T17:35:26.354Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1e/b3723d8ff64ab548c38d87055483714fefe6ee20e0189b62352b5e015bb1/scipy-1.16.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2d1ae2cf0c350e7705168ff2429962a89ad90c2d49d1dd300686d8b2a5af22fc", size = 38640178, upload-time = "2025-10-28T17:35:35.304Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f3/d854ff38789aca9b0cc23008d607ced9de4f7ab14fa1ca4329f86b3758ca/scipy-1.16.3-cp313-cp313t-win_arm64.whl", hash = "sha256:0c623a54f7b79dd88ef56da19bc2873afec9673a48f3b85b18e4d402bdd29a5a", size = 25803246, upload-time = "2025-10-28T17:35:42.155Z" }, + { url = "https://files.pythonhosted.org/packages/99/f6/99b10fd70f2d864c1e29a28bbcaa0c6340f9d8518396542d9ea3b4aaae15/scipy-1.16.3-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:875555ce62743e1d54f06cdf22c1e0bc47b91130ac40fe5d783b6dfa114beeb6", size = 36606469, upload-time = "2025-10-28T17:36:08.741Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/043b54f2319f48ea940dd025779fa28ee360e6b95acb7cd188fad4391c6b/scipy-1.16.3-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bb61878c18a470021fb515a843dc7a76961a8daceaaaa8bad1332f1bf4b54657", size = 28872043, upload-time = "2025-10-28T17:36:16.599Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/24b7e50cc1c4ee6ffbcb1f27fe9f4c8b40e7911675f6d2d20955f41c6348/scipy-1.16.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2622206f5559784fa5c4b53a950c3c7c1cf3e84ca1b9c4b6c03f062f289ca26", size = 20862952, upload-time = "2025-10-28T17:36:22.966Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3a/3e8c01a4d742b730df368e063787c6808597ccb38636ed821d10b39ca51b/scipy-1.16.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7f68154688c515cdb541a31ef8eb66d8cd1050605be9dcd74199cbd22ac739bc", size = 23508512, upload-time = "2025-10-28T17:36:29.731Z" }, + { url = "https://files.pythonhosted.org/packages/1f/60/c45a12b98ad591536bfe5330cb3cfe1850d7570259303563b1721564d458/scipy-1.16.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3c820ddb80029fe9f43d61b81d8b488d3ef8ca010d15122b152db77dc94c22", size = 33413639, upload-time = "2025-10-28T17:36:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/71/bc/35957d88645476307e4839712642896689df442f3e53b0fa016ecf8a3357/scipy-1.16.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d3837938ae715fc0fe3c39c0202de3a8853aff22ca66781ddc2ade7554b7e2cc", size = 35704729, upload-time = "2025-10-28T17:36:46.547Z" }, + { url = "https://files.pythonhosted.org/packages/3b/15/89105e659041b1ca11c386e9995aefacd513a78493656e57789f9d9eab61/scipy-1.16.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aadd23f98f9cb069b3bd64ddc900c4d277778242e961751f77a8cb5c4b946fb0", size = 36086251, upload-time = "2025-10-28T17:36:55.161Z" }, + { url = "https://files.pythonhosted.org/packages/1a/87/c0ea673ac9c6cc50b3da2196d860273bc7389aa69b64efa8493bdd25b093/scipy-1.16.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b7c5f1bda1354d6a19bc6af73a649f8285ca63ac6b52e64e658a5a11d4d69800", size = 38716681, upload-time = "2025-10-28T17:37:04.1Z" }, + { url = "https://files.pythonhosted.org/packages/91/06/837893227b043fb9b0d13e4bd7586982d8136cb249ffb3492930dab905b8/scipy-1.16.3-cp314-cp314-win_amd64.whl", hash = "sha256:e5d42a9472e7579e473879a1990327830493a7047506d58d73fc429b84c1d49d", size = 39358423, upload-time = "2025-10-28T17:38:20.005Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/28bce0355e4d34a7c034727505a02d19548549e190bedd13a721e35380b7/scipy-1.16.3-cp314-cp314-win_arm64.whl", hash = "sha256:6020470b9d00245926f2d5bb93b119ca0340f0d564eb6fbaad843eaebf9d690f", size = 26135027, upload-time = "2025-10-28T17:38:24.966Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6f/69f1e2b682efe9de8fe9f91040f0cd32f13cfccba690512ba4c582b0bc29/scipy-1.16.3-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:e1d27cbcb4602680a49d787d90664fa4974063ac9d4134813332a8c53dbe667c", size = 37028379, upload-time = "2025-10-28T17:37:14.061Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2d/e826f31624a5ebbab1cd93d30fd74349914753076ed0593e1d56a98c4fb4/scipy-1.16.3-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:9b9c9c07b6d56a35777a1b4cc8966118fb16cfd8daf6743867d17d36cfad2d40", size = 29400052, upload-time = "2025-10-28T17:37:21.709Z" }, + { url = "https://files.pythonhosted.org/packages/69/27/d24feb80155f41fd1f156bf144e7e049b4e2b9dd06261a242905e3bc7a03/scipy-1.16.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:3a4c460301fb2cffb7f88528f30b3127742cff583603aa7dc964a52c463b385d", size = 21391183, upload-time = "2025-10-28T17:37:29.559Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d3/1b229e433074c5738a24277eca520a2319aac7465eea7310ea6ae0e98ae2/scipy-1.16.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:f667a4542cc8917af1db06366d3f78a5c8e83badd56409f94d1eac8d8d9133fa", size = 23930174, upload-time = "2025-10-28T17:37:36.306Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/d9e148b0ec680c0f042581a2be79a28a7ab66c0c4946697f9e7553ead337/scipy-1.16.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f379b54b77a597aa7ee5e697df0d66903e41b9c85a6dd7946159e356319158e8", size = 33497852, upload-time = "2025-10-28T17:37:42.228Z" }, + { url = "https://files.pythonhosted.org/packages/2f/22/4e5f7561e4f98b7bea63cf3fd7934bff1e3182e9f1626b089a679914d5c8/scipy-1.16.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4aff59800a3b7f786b70bfd6ab551001cb553244988d7d6b8299cb1ea653b353", size = 35798595, upload-time = "2025-10-28T17:37:48.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/42/6644d714c179429fc7196857866f219fef25238319b650bb32dde7bf7a48/scipy-1.16.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:da7763f55885045036fabcebd80144b757d3db06ab0861415d1c3b7c69042146", size = 36186269, upload-time = "2025-10-28T17:37:53.72Z" }, + { url = "https://files.pythonhosted.org/packages/ac/70/64b4d7ca92f9cf2e6fc6aaa2eecf80bb9b6b985043a9583f32f8177ea122/scipy-1.16.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa6eea95283b2b8079b821dc11f50a17d0571c92b43e2b5b12764dc5f9b285d", size = 38802779, upload-time = "2025-10-28T17:37:59.393Z" }, + { url = "https://files.pythonhosted.org/packages/61/82/8d0e39f62764cce5ffd5284131e109f07cf8955aef9ab8ed4e3aa5e30539/scipy-1.16.3-cp314-cp314t-win_amd64.whl", hash = "sha256:d9f48cafc7ce94cf9b15c6bffdc443a81a27bf7075cf2dcd5c8b40f85d10c4e7", size = 39471128, upload-time = "2025-10-28T17:38:05.259Z" }, + { url = "https://files.pythonhosted.org/packages/64/47/a494741db7280eae6dc033510c319e34d42dd41b7ac0c7ead39354d1a2b5/scipy-1.16.3-cp314-cp314t-win_arm64.whl", hash = "sha256:21d9d6b197227a12dcbf9633320a4e34c6b0e51c57268df255a0942983bac562", size = 26464127, upload-time = "2025-10-28T17:38:11.34Z" }, +] + [[package]] name = "setuptools" version = "80.9.0" From 0a7e74f0bec11fc2ba6e7100c1f138b983e68e08 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 01:44:03 +0100 Subject: [PATCH 071/107] =?UTF-8?q?feat:=20rajout=20de=20la=20fonctionnabi?= =?UTF-8?q?lit=C3=A9=20de=20toggle=20le=20lancement=20du=20stream=20ou=20n?= =?UTF-8?q?on=20depuis=20le=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Camera.py | 206 +++++++++++++++++++++++++++--------------- src/HL/Camera_serv.py | 72 ++++----------- src/HL/Serveur_mq.py | 42 +++------ 3 files changed, 164 insertions(+), 156 deletions(-) diff --git a/src/HL/Camera.py b/src/HL/Camera.py index 77e23276..5fd43e63 100644 --- a/src/HL/Camera.py +++ b/src/HL/Camera.py @@ -8,7 +8,10 @@ import shutil import scipy as sp import time -from camera_server import get_current_frame, start_camera_stream + +from picamera2 import Picamera2 +from picamera2.encoders import JpegEncoder +from picamera2.outputs import FileOutput N_IMAGES = 100 # Number of images to capture SAVE_DIR = "Captured_Frames" # Directory to save frames DEBUG_DIR = "Debug" # Directory for debug images @@ -21,79 +24,131 @@ COLOR_THRESHOLD = 20 # Threshold for color intensity difference Y_OFFSET = -80 # Offset for the y-axis in the image +from picamera2.outputs import Output + +class JpegCallback(Output): + def __init__(self, parent_cam): + super().__init__() + self.parent = parent_cam + + def outputframe(self, frame, keyframe=True): + # frame = bytes JPEG + self.parent._on_new_frame(frame) + + + + +from Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer + + class Camera: - def __init__(self): - os.environ["LIBCAMERA_LOG_LEVELS"] = "WARN" - self.debug_counter = 0 # Counter for debug images - self.image_no = 0 - self.image_path = None + def __init__(self, size=(640,480), port=8000): + self.size = size + self.port = port + + self.streaming = False + self.stream_thread = None + self.picam2 = None self.last_frame = None - self.flag_stop = False - self.thread = None # Stocke le thread pour contrôle ultérieur - - camlogger = log.getLogger("picamera2") - camlogger.setLevel(log.INFO) + self.debug_counter = 0 + self.image_no = 0 - os.makedirs(SAVE_DIR, exist_ok=True) # Crée le répertoire s'il n'existe pas - os.makedirs(DEBUG_DIR, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas - os.makedirs(DEBUG_DIR_wayfinding, exist_ok=True) # Crée le répertoire de débogage s'il n'existe pas - - self.capture_image() # Capture une image pour initialiser le répertoire de sauvegarde - - def capture_image(self): - jpeg = get_current_frame() - if jpeg is None: + # Démarrage en mode "acquisition locale sans stream" + self._start_local_capture() + + + # ---------------------------------------------------------- + # Capture locale (sans MJPEG server) + # ---------------------------------------------------------- + def _start_local_capture(self): + """Démarre la capture interne (sans streaming MJPEG).""" + self.picam2 = Picamera2() + self.picam2.configure(self.picam2.create_video_configuration( + main={"size": self.size} + )) + + self.output = StreamOutput() + self.picam2.start_recording(JpegEncoder(), FileOutput(self.output)) + + # Thread pour mettre à jour last_frame + self.capture_thread = threading.Thread( + target=self._update_last_frame_loop, + daemon=True + ) + self.capture_thread.start() + + + def _update_last_frame_loop(self): + """Récupère en continu la dernière frame JPEG.""" + while True: + jpeg = frame_buffer.get() + if jpeg: + np_frame = cv2.imdecode(np.frombuffer(jpeg, np.uint8), cv2.IMREAD_COLOR) + if np_frame is not None: + self.last_frame = cv2.cvtColor(np_frame, cv2.COLOR_BGR2RGB) time.sleep(0.01) - return self.last_frame - - np_frame = cv2.imdecode(np.frombuffer(jpeg, dtype=np.uint8), cv2.IMREAD_COLOR) - if np_frame is None: - return self.last_frame - - frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - self.last_frame = frame - # compatibilité avec ton ancien système - self.image_path = os.path.join(SAVE_DIR, f"frame_{self.image_no:02d}.jpg") - Image.fromarray(frame).save(self.image_path) - self.image_no += 1 - if self.image_no >= N_IMAGES: - self.image_no = 0 + # ---------------------------------------------------------- + # Contrôle streaming MJPEG + # ---------------------------------------------------------- + def start_stream(self): + if self.streaming: + return + import Camera_serv + Camera_serv.streaming_enabled = True - return Image.fromarray(frame) - - def capture_images_continus(self): - while not self.flag_stop: - for i in range(N_IMAGES): - self.capture_image() - if self.flag_stop: - break - self.image_no = 0 - - def start(self): - """Démarre la capture en continu dans un thread séparé.""" - if self.thread is None or not self.thread.is_alive(): # Évite de lancer plusieurs threads - self.flag_stop = False # Réinitialiser le flag d'arrêt - self.thread = threading.Thread(target=self.capture_images_continus, daemon=True) - self.thread.start() - - def stop(self): - """Arrête la capture et attend que le thread se termine proprement.""" - self.flag_stop = True - if self.thread is not None: - self.thread.join() # Attendre la fin du thread avant de continuer - if self.cap: - self.cap.release() - shutil.rmtree(SAVE_DIR) # Supprime le répertoire des images capturées - + self.httpd = StreamServer(("", self.port), StreamHandler) + + def run_server(): + print(f"[INFO] MJPEG stream on http://:{self.port}/stream.mjpg") + try: + self.httpd.serve_forever() + except Exception as e: + print("Serveur MJPEG arrêté:", e) + + self.stream_thread = threading.Thread(target=run_server, daemon=True) + self.stream_thread.start() + self.streaming = True + + + + def stop_stream(self): + if not self.streaming: + return + + import Camera_serv + Camera_serv.streaming_enabled = False + + print("[INFO] Shutting down MJPEG server...") + + self.httpd.shutdown() + self.httpd.server_close() + self.stream_thread.join() + + self.streaming = False + print("[INFO] Stream stopped.") + + + + + def toggle_stream(self): + if self.streaming: + print("[INFO] Stopping stream") + self.stop_stream() + else: + print("[INFO] Starting stream") + self.start_stream() + + + # ---------------------------------------------------------- + # Interface publique + # ---------------------------------------------------------- def get_last_image(self): - last_no = self.image_no - 1 if self.image_no > 0 else 99 - path = os.path.join(SAVE_DIR, f"frame_{last_no:02d}.jpg") - image = Image.open(path).convert("RGB") - return np.array(image) + return self.last_frame + def camera_matrix(self, vector_size=128, image=None): """ @@ -225,11 +280,20 @@ def is_running_in_reversed(self, image = None, LEFT_IS_GREEN=True): if __name__ == "__main__": log.basicConfig(level=log.DEBUG) - start_camera_stream() - image_path = "src\HL\wrong_direction33.jpg" # Replace with your image path + camera = Camera() - camera.start() - pil_image = Image.open(image_path).convert("RGB") # Open and ensure it's in RGB format - image = np.array(pil_image) # Convert to NumPy array - - print(camera.is_running_in_reversed(image=image, LEFT_IS_GREEN=True)) # Check if the car is running in reverse \ No newline at end of file + + print("Attente frame...") + while camera.get_last_image() is None: + time.sleep(0.05) + + frame = camera.get_last_image() + matrix = camera.camera_matrix() + print("camera_matrix OK") + + input("Appuyer pour lancer le stream...") + camera.toggle_stream() + + while True: + if input("Toggle ? ") == "o": + camera.toggle_stream() diff --git a/src/HL/Camera_serv.py b/src/HL/Camera_serv.py index b06053a4..223a33e3 100644 --- a/src/HL/Camera_serv.py +++ b/src/HL/Camera_serv.py @@ -1,16 +1,12 @@ +# camera_server.py import io -import threading import logging from http import server import socketserver -from picamera2 import Picamera2 -from picamera2.encoders import JpegEncoder -from picamera2.outputs import FileOutput from threading import Condition -# ------------------------------------------------------------------- -# Stockage global de la dernière frame reçue -# ------------------------------------------------------------------- +streaming_enabled = True +from Camera_serv import streaming_enabled class FrameBuffer: def __init__(self): self.frame = None @@ -22,24 +18,17 @@ def update(self, data): self.condition.notify_all() def get(self): - # Ça te donne la dernière frame (ou None au début) return self.frame frame_buffer = FrameBuffer() -# ------------------------------------------------------------------- -# Output pour Picamera2 (reçoit les JPEG du JpegEncoder) -# ------------------------------------------------------------------- class StreamOutput(io.BufferedIOBase): def write(self, buf): frame_buffer.update(buf) -# ------------------------------------------------------------------- -# Serveur MJPEG : /stream.mjpg -# ------------------------------------------------------------------- class StreamHandler(server.BaseHTTPRequestHandler): def do_GET(self): if self.path == "/stream.mjpg": @@ -50,17 +39,21 @@ def do_GET(self): self.end_headers() try: - while True: - with frame_buffer.condition: - frame_buffer.condition.wait() - frame = frame_buffer.frame - - self.wfile.write(b"--FRAME\r\n") - self.send_header("Content-Type", "image/jpeg") - self.send_header("Content-Length", len(frame)) - self.end_headers() - self.wfile.write(frame) - self.wfile.write(b"\r\n") + try: + while streaming_enabled: + with frame_buffer.condition: + frame_buffer.condition.wait() + frame = frame_buffer.frame + + self.wfile.write(b"--FRAME\r\n") + self.send_header("Content-Type", "image/jpeg") + self.send_header("Content-Length", len(frame)) + self.end_headers() + self.wfile.write(frame) + self.wfile.write(b"\r\n") + + except Exception as e: + logging.warning("Client déconnecté: %s", e) except Exception as e: logging.warning("Client déconnecté: %s", e) @@ -71,32 +64,3 @@ def do_GET(self): class StreamServer(socketserver.ThreadingMixIn, server.HTTPServer): daemon_threads = True allow_reuse_address = True - - -# ------------------------------------------------------------------- -# Thread principal de capture + serveur HTTP -# ------------------------------------------------------------------- -def start_camera_stream(port=8000, size=(640, 480)): - picam2 = Picamera2() - picam2.configure(picam2.create_video_configuration( - main={"size": size} - )) - - output = StreamOutput() - picam2.start_recording(JpegEncoder(), FileOutput(output)) - - httpd = StreamServer(("", port), StreamHandler) - print(f"[INFO] Serveur MJPEG en ligne sur http://:{port}/stream.mjpg") - - try: - httpd.serve_forever() - finally: - picam2.stop_recording() - - -# ------------------------------------------------------------------- -# Fonction utilitaire pour d’autres scripts -# ------------------------------------------------------------------- -def get_current_frame(): - """Retourne la dernière frame JPEG""" - return frame_buffer.get() diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index c2c5a7d4..f46a8f26 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -21,7 +21,7 @@ from get_ip import get_ip, check_ssh_connections import subprocess from Lidar import Lidar -from Camera import Camera, start_camera_stream +from Camera import Camera from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET @@ -132,6 +132,12 @@ def __init__(self): "info" : "" }, 5: { + "name" : "Streaming Video", + "type" : "function", + "path" : lambda: self.toggle_video_stream(), + "info" : "" + }, + 6: { "name" : "poweroff", "type" : "bash", "path" : "sudo poweroff", @@ -237,17 +243,6 @@ def _initialize_lidar(self): except Exception as e: print(f"Error initializing Lidar: {e}") - def _initialize_camera(self): - """Initialize the camera.""" - for i in range(10): - try: - self.camera = Camera() - print("Camera OK") - return - except Exception as e: - print("Camera retry", i, e) - time.sleep(0.5) - raise RuntimeError("Camera KO après 10 essais") #--------------------------------------------------------------------------------------------------- # fonction pour la communication @@ -313,21 +308,6 @@ def envoie_donnee(self, socket): "direction" : self.direction, "timestamp": time.time() - self.initial_time }) - elif info["cmd"] == "cam": - if self.camera_image is None: - socket.send_json({"cam": None}) - continue - - buffer = BytesIO() - self.camera_image.save(buffer, format="JPEG") - jpg_bytes = buffer.getvalue() - jpg_b64 = base64.b64encode(jpg_bytes).decode() - - socket.send_json({ - "cam": jpg_b64 - }) - continue - else : socket.send_json({"Error" : "not understand"}) @@ -343,10 +323,11 @@ def lidar_update_data(self): time.sleep(1) - def _start_video_stream(self): + def toggle_video_stream(self): """Start continuous JPEG compressed video streaming via ZMQ.""" try: - start_camera_stream(port=8000) + self.camera.toggle_stream() + print("camera streaming lancé") except: print("Camera Down...") @@ -428,8 +409,7 @@ def main(self): threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() - threading.Thread(target=self._start_video_stream, daemon=True).start() - + while True: self.Idle() From 4a0d602ac020eb96316d7013eb81de94b5539a23 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 15:31:44 +0100 Subject: [PATCH 072/107] =?UTF-8?q?fix:=20petit=20fix=20sur=20coment=20son?= =?UTF-8?q?=20lanc=C3=A9=20les=20fonctions=20depuis=20le=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index f46a8f26..2f45bc28 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -327,7 +327,6 @@ def toggle_video_stream(self): """Start continuous JPEG compressed video streaming via ZMQ.""" try: self.camera.toggle_stream() - print("camera streaming lancé") except: print("Camera Down...") @@ -355,6 +354,8 @@ def start_process(self,num_programme): print(e) if (num_programme == self.last_programme): + if self.programme_actuel["type"] == "function": # les fonction on besoin d'êter rappelé pour pouvoir les arreter + self.programme_actuel["path"]() self.last_programme = 0 # pour pouvoir lancer le programme en rapuyant sur le bouton return # si on est sur le même programme on kill et c'est tout @@ -398,7 +399,7 @@ def switch_remote_control(self): self.programme[self.last_programme]["info"] = "" else: self.remote_control = True - threading.Thread(target=self.car_controle, args=(public,False,), daemon=True).start() + threading.Thread(target=self.car_controle, args=(public,False,), daemon=True).start() def main(self): self.bp_next.when_pressed = self.bouton_next From 0e2a08286ab5990603a717c06648418149de40e4 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 16:01:08 +0100 Subject: [PATCH 073/107] =?UTF-8?q?fix:=20kill=20du=20thread=20de=20remote?= =?UTF-8?q?=20control=20maintenant=20op=C3=A9rationnelle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 2f45bc28..fc8b70ab 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -100,6 +100,7 @@ def __init__(self): self.process_output = "" self.last_programme = 0 self.process = None + self.temp = None self.programme = { 0: { "name" : "Ssh to :\n" + self.ip, @@ -284,14 +285,20 @@ def i2c_received(self): - def car_controle(self,socket, is_private): + def car_controle(self,sock, is_private): """ on regarde si il s'agit de lappelle pour le control interne (is_private) ou si on veux prendre le controle depuis le pc.""" + sock.settimeout(0.1) while is_private or self.remote_control: - data, ip = socket.recvfrom(1024) - self.vitesse_d, self.direction = struct.unpack("ff", data) - self.last_cmd_time = time.time() + try: + data, ip = sock.recvfrom(1024) + self.vitesse_d, self.direction = struct.unpack("ff", data) + self.last_cmd_time = time.time() + except socket.timeout: + continue + + def envoie_donnee(self, socket): """ on regarde si il s'agit de lappelle pour le control interne From 298e4306a0010aa669cbdf7ee52c616ec3110b03 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 16:23:08 +0100 Subject: [PATCH 074/107] fix : diminution du nombre de thread actif. --- src/HL/Serveur_mq.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index fc8b70ab..b8583a27 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -340,14 +340,7 @@ def toggle_video_stream(self): #--------------------------------------------------------------------------------------------------- # Processus #--------------------------------------------------------------------------------------------------- - def stream_process_output(self, proc): - for line in proc.stdout: - self.process_output = line.decode().strip() - """ - lines = proc.stdout.split("\n") - size = 3 - chunks = [l[i * size : (i+1) * size] for l in lines for i in range(len(l) // size + 1)] - print(chunks)""" + def start_process(self,num_programme): @@ -356,7 +349,7 @@ def start_process(self,num_programme): if self.process is not None: try: - os.killpg(os.getpgid(self.process.pid), signal.SIGTERM) + os.killpg(os.getpgid(self.process.pid), signal.SIGKILL) except Exception as e: print(e) @@ -380,15 +373,13 @@ def start_process(self,num_programme): preexec_fn=os.setsid ) - threading.Thread(target=self.stream_process_output, args=(self.process,), daemon=True).start() + elif self.programme_actuel["type"] == "python": self.process = subprocess.Popen(["uv","run",self.programme_actuel["path"]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid ) - - threading.Thread(target=self.stream_process_output, args=(self.process,), daemon=True).start() elif self.programme_actuel["type"] == "function": self.programme_actuel["path"]() @@ -419,6 +410,7 @@ def main(self): threading.Thread(target=self.lidar_update_data, daemon=True).start() while True: + print("THREAD COUNT:", len(threading.enumerate())) self.Idle() #--------------------------------------------------------------------------------------------------- From dc5b4184389de3bfcfc1116376dcb3c2a51742bb Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 16:36:27 +0100 Subject: [PATCH 075/107] =?UTF-8?q?rajout,=20d'information=20a=20envoy?= =?UTF-8?q?=C3=A9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index b8583a27..76b7aedc 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -307,14 +307,21 @@ def envoie_donnee(self, socket): from io import BytesIO while True: info = socket.recv_json() - if info["cmd"] == "info": + if info["get"] == "info": socket.send_json({ "voltage_lipo": self.voltage_lipo, "voltage_nimh": self.voltage_nimh, "vitesse_reelle": self.vitesse_r, + "vitesse_demande": self.vitesse_d, "direction" : self.direction, "timestamp": time.time() - self.initial_time }) + elif info["cmd"] == "menu": + if info["menu"] in self.programme.key: + start_process(self,info["menu"]) + socket.send_json({"status":"ok"}) + elif info["get"] == "menu": + socket.send_json(self.programme) else : socket.send_json({"Error" : "not understand"}) @@ -410,7 +417,6 @@ def main(self): threading.Thread(target=self.lidar_update_data, daemon=True).start() while True: - print("THREAD COUNT:", len(threading.enumerate())) self.Idle() #--------------------------------------------------------------------------------------------------- From 073cdae0e6e1c88ed2293e65623d281636307123 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 2 Dec 2025 16:37:06 +0100 Subject: [PATCH 076/107] z --- src/HL/Serveur_mq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 76b7aedc..6c54a148 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -318,7 +318,7 @@ def envoie_donnee(self, socket): }) elif info["cmd"] == "menu": if info["menu"] in self.programme.key: - start_process(self,info["menu"]) + start_process(self,info["menu"]) #lancement du menu reçue socket.send_json({"status":"ok"}) elif info["get"] == "menu": socket.send_json(self.programme) From 574293ea833a9d4c1033167b711b442aebecba04 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 3 Dec 2025 00:30:19 +0100 Subject: [PATCH 077/107] fix: optimistion de Camera_serv et Camera pour avoir un flux video plus rapide. --- src/HL/Camera.py | 17 ++++++----- src/HL/Camera_serv.py | 67 +++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/HL/Camera.py b/src/HL/Camera.py index 5fd43e63..174c9360 100644 --- a/src/HL/Camera.py +++ b/src/HL/Camera.py @@ -42,7 +42,7 @@ def outputframe(self, frame, keyframe=True): class Camera: - def __init__(self, size=(640,480), port=8000): + def __init__(self, size=(1280, 720), port=8000): self.size = size self.port = port @@ -63,16 +63,19 @@ def __init__(self, size=(640,480), port=8000): # Capture locale (sans MJPEG server) # ---------------------------------------------------------- def _start_local_capture(self): - """Démarre la capture interne (sans streaming MJPEG).""" self.picam2 = Picamera2() - self.picam2.configure(self.picam2.create_video_configuration( - main={"size": self.size} - )) + config = self.picam2.create_video_configuration( + main={"size": (1280, 720)}, # plus large, moins zoomé + controls={"FrameRate": 30} # FPS stable + ) + self.picam2.configure(config) self.output = StreamOutput() - self.picam2.start_recording(JpegEncoder(), FileOutput(self.output)) - # Thread pour mettre à jour last_frame + # Qualité JPEG custom + self.picam2.start_recording(JpegEncoder(q=10), FileOutput(self.output)) + + # thread lecture last_frame self.capture_thread = threading.Thread( target=self._update_last_frame_loop, daemon=True diff --git a/src/HL/Camera_serv.py b/src/HL/Camera_serv.py index 223a33e3..505cb2f8 100644 --- a/src/HL/Camera_serv.py +++ b/src/HL/Camera_serv.py @@ -4,18 +4,21 @@ from http import server import socketserver from threading import Condition - streaming_enabled = True + from Camera_serv import streaming_enabled + class FrameBuffer: def __init__(self): self.frame = None self.condition = Condition() def update(self, data): - with self.condition: - self.frame = data - self.condition.notify_all() + # Only accept full JPEG frames + if data.startswith(b'\xff\xd8') and data.endswith(b'\xff\xd9'): + with self.condition: + self.frame = data + self.condition.notify_all() def get(self): return self.frame @@ -27,38 +30,40 @@ def get(self): class StreamOutput(io.BufferedIOBase): def write(self, buf): frame_buffer.update(buf) + return len(buf) class StreamHandler(server.BaseHTTPRequestHandler): def do_GET(self): - if self.path == "/stream.mjpg": - self.send_response(200) - self.send_header('Cache-Control', 'no-cache') - self.send_header('Content-Type', - 'multipart/x-mixed-replace; boundary=FRAME') - self.end_headers() - - try: - try: - while streaming_enabled: - with frame_buffer.condition: - frame_buffer.condition.wait() - frame = frame_buffer.frame - - self.wfile.write(b"--FRAME\r\n") - self.send_header("Content-Type", "image/jpeg") - self.send_header("Content-Length", len(frame)) - self.end_headers() - self.wfile.write(frame) - self.wfile.write(b"\r\n") - - except Exception as e: - logging.warning("Client déconnecté: %s", e) - - except Exception as e: - logging.warning("Client déconnecté: %s", e) - else: + if self.path != "/stream.mjpg": self.send_error(404) + return + + self.send_response(200) + self.send_header("Age", "0") + self.send_header("Cache-Control", "no-cache, private") + self.send_header("Pragma", "no-cache") + self.send_header("Content-Type", "multipart/x-mixed-replace; boundary=FRAME") + self.end_headers() + + try: + while streaming_enabled: + with frame_buffer.condition: + frame_buffer.condition.wait() + frame = frame_buffer.frame + + if frame is None: + continue + + self.wfile.write(b"--FRAME\r\n") + self.send_header("Content-Type", "image/jpeg") + self.send_header("Content-Length", len(frame)) + self.end_headers() + self.wfile.write(frame) + self.wfile.write(b"\r\n") + + except Exception as e: + logging.warning("Client disconnected: %s", e) class StreamServer(socketserver.ThreadingMixIn, server.HTTPServer): From aac925bcf3e3a71ef5f6ae5c8e55470ed749f5a1 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 02:36:52 +0100 Subject: [PATCH 078/107] feat: utilisation du nouveau system de programme en passant tout par des classe --- scripts/commande_PS4.py | 169 +++++++++++++++++++---------------- scripts/startup.sh | 2 +- src/HL/Autotech_constant.py | 5 +- src/HL/Camera.py | 18 ++++ src/HL/Poweroff.py | 22 +++++ src/HL/RemoteControl.py | 36 ++++++++ src/HL/Serveur_mq.py | 170 ++++++++++++++++-------------------- src/HL/SshProgramme.py | 8 ++ src/HL/programme.py | 27 ++++++ 9 files changed, 283 insertions(+), 174 deletions(-) create mode 100644 src/HL/Poweroff.py create mode 100644 src/HL/RemoteControl.py create mode 100644 src/HL/SshProgramme.py create mode 100644 src/HL/programme.py diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index c7ce0857..63d385cb 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -1,31 +1,28 @@ from pyPS4Controller.controller import Controller import time +import os from threading import Thread - +from src.HL.Autotech_constant import SOCKET_ADRESS +from programme import Program ################################################### #Intialisation du protocole zmq ################################################## -import socket -import struct -################################################### -# Init ZMQ -################################################### -sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -def envoie_donnee(): - global vitesse_m, direction_d +def envoie_donnee(Voiture): #si utilisation de la voiture directement + print("lancement de l'i2c") + import smbus + import struct + bus = smbus.SMBus(1) + SLAVE_ADDRESS = 0x08 while True: - packet = struct.pack("ff", vitesse_m, direction_d) - sock.sendto(packet, ("127.0.0.1", 5555)) - time.sleep(0.05) - + try : + data = struct.pack(' 0): - set_vitesse_m_ms(0) + self.vitesse_mms = 0 else: - set_vitesse_m_ms(vit) + self.vitesse_mms = vit def on_L2_release(self): #arrete la voiture lorsque L2 est arrété d'étre préssé. - set_vitesse_m_ms(0) - - -# boucle principal -controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False) -try: - Thread(target = envoie_donnee, daemon=True).start() - controller.listen(timeout=60) - -except KeyboardInterrupt: - print("Arrêt du programme") - controller.stop() - exit(0) + self.vitesse_mms = 0 + + def on_L3_up(self,value): + pass + def on_L3_down(self,value): + pass + def on_L3_y_at_rest(self): + pass +if __name__ == "__main__": + controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False) + try: + Thread(target = envoie_donnee,args=(controller,), daemon=True).start() + controller.listen(timeout=60) + except KeyboardInterrupt: + print("Arrêt du programme") + controller.stop() + exit(0) diff --git a/scripts/startup.sh b/scripts/startup.sh index 0f798a2c..5892df06 100755 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -2,7 +2,7 @@ # Specify the PATH export PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" - +export PYTHONPATH=$PYTHONPATH:/home/intech/CoVAPSy # Wait until WiFi is acquired while ! ping -c 1 google.com &> /dev/null; do diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index 8829095c..0ac260ca 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -24,4 +24,7 @@ Temperature = 0.7 # Temperature parameter for softmax function, used to control the sharpness of the distribution resols around 1 # the higher the temperature the more unprobalbe actions become probable, the lower the temperature the more probable actions become probable. -# In our case Higher temperature means less agressive driving and lower temperature means more aggressive driving. \ No newline at end of file +# In our case Higher temperature means less agressive driving and lower temperature means more aggressive driving. + +import logging +LOGGING_LEVEL = logging.DEBUG # can be either NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL \ No newline at end of file diff --git a/src/HL/Camera.py b/src/HL/Camera.py index 174c9360..12cae563 100644 --- a/src/HL/Camera.py +++ b/src/HL/Camera.py @@ -39,6 +39,24 @@ def outputframe(self, frame, keyframe=True): from Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer +from programme import Program + +class ProgramStreamCamera(Program): + def __init__(self,camera): + self.name = "Streaming Video" + self.camera = camera + self.running = False + self.controls_car = False + + def start(self): + self.running = True + self.camera.start_stream() + + def kill(self): + self.running = False + self.camera.stop_stream() + + class Camera: diff --git a/src/HL/Poweroff.py b/src/HL/Poweroff.py new file mode 100644 index 00000000..2eac5e7e --- /dev/null +++ b/src/HL/Poweroff.py @@ -0,0 +1,22 @@ +import subprocess +from programme import Program + +class Poweroff(Program): + def __init__(self): + super().__init__() + self.name = "Power off" + self.controls_car = False + self.running = False + + def kill(): + pass + + def start(): + subprocess.Popen( + "sudo poweroff", + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + preexec_fn=os.setsid + ) + \ No newline at end of file diff --git a/src/HL/RemoteControl.py b/src/HL/RemoteControl.py new file mode 100644 index 00000000..6d3c0fb3 --- /dev/null +++ b/src/HL/RemoteControl.py @@ -0,0 +1,36 @@ +from programme import Program +import struct +import socket + +class RemoteControl(Program): + def __init__(self): + super().__init__() + self.name = "Remote Control" + self.controls_car = True + self.running = False + self.vitesse_d = 0 + self.direction = 0 + + #initialisation + self.public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.public.bind(("0.0.0.0", 5556)) + + def car_controle(self,sock): + """ on regarde si il s'agit de lappelle pour le control interne + (is_private) ou si on veux prendre le controle depuis le pc.""" + sock.settimeout(0.1) + + while self.running: + try: + data, ip = sock.recvfrom(1024) + self.vitesse_d, self.direction = struct.unpack("ff", data) + self.last_cmd_time = time.time() + except socket.timeout: + continue + + def start(self): + self.running = True + threading.Thread(target=self.car_controle, args=(public,), daemon=True).start() + + def kill(self): + self.running = False \ No newline at end of file diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 6c54a148..8830cb6c 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -24,6 +24,12 @@ from Camera import Camera from Autotech_constant import SOCKET_ADRESS, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET +#différent programme +from scripts.commande_PS4 import PS4ControllerProgram +from SshProgramme import SshProgramme +from RemoteControl import RemoteControl +from Poweroff import Poweroff +from Camera import ProgramStreamCamera serial = i2c(port=1, address=0x3C) device = ssd1306(serial) @@ -61,8 +67,7 @@ public.setsockopt_string(zmq.SUBSCRIBE, "") """ # on envoie en udp les commandes de la ps4 -public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -public.bind(("0.0.0.0", 5556)) + private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) private.bind(("127.0.0.1", 5555)) @@ -101,50 +106,62 @@ def __init__(self): self.last_programme = 0 self.process = None self.temp = None - self.programme = { - 0: { - "name" : "Ssh to :\n" + self.ip, - "type" : "", - "path" : "", - "info" : "no" - }, - 1: { - "name" : "Auto Driving", - "type" : "python", - "path" : "", - "info" : "" - }, - 2: { - "name" : "PS4 Controller", - "type" : "python", - "path" : "./scripts/commande_PS4.py", - "info" : "" - }, - 3: { - "name" : "Connect Controller", - "type" : "bash", - "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", - "info" : "no" - }, - 4: { - "name" : "Remote control", - "type" : "function", - "path" : lambda: self.switch_remote_control(), - "info" : "" - }, - 5: { - "name" : "Streaming Video", - "type" : "function", - "path" : lambda: self.toggle_video_stream(), - "info" : "" - }, - 6: { - "name" : "poweroff", - "type" : "bash", - "path" : "sudo poweroff", - "info" : "" - } - } + # self.programme = { + # 0: { + # "name" : "Ssh to :\n" + self.ip, + # "type" : "", + # "path" : "", + # "info" : "no" + # }, + # 1: { + # "name" : "Auto Driving", + # "type" : "python", + # "path" : "", + # "info" : "", + # "controll_car" : "yes" + # }, + # 2: { + # "name" : "PS4 Controller", + # "type" : "function", + # "path" : lambda: toggle_commande_PS4(self.commande_PS4), + # "info" : "", + # "controll_car" : "yes" + # }, + # 3: { + # "name" : "Connect Controller", + # "type" : "bash", + # "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", + # "info" : "no" + # }, + # 4: { + # "name" : "Remote control", + # "type" : "function", + # "path" : lambda: self.switch_remote_control(), + # "info" : "", + # "controll_car" : "yes" + # }, + # 5: { + # "name" : "Streaming Video", + # "type" : "function", + # "path" : lambda: self.toggle_video_stream(), + # "info" : "" + # }, + # 6: { + # "name" : "poweroff", + # "type" : "bash", + # "path" : "sudo poweroff", + # "info" : "" + # } + # } + + self.camera = Camera() + self.program = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] + + + + + #initialisation de commande + self.commande_PS4 = initialize_commande_PS4() #donnée du lidar self.lidar = None @@ -155,7 +172,6 @@ def __init__(self): self.Screen = 0 self.State = 0 self.scroll_offset = 3 - self.camera = Camera() #----------------------------------------------------------------------------------------------------- # affichage de l'écrans @@ -212,11 +228,7 @@ def Idle(self): #Enable chossing between states self.led1.off() if (self.Screen < len(self.programme)): - if self.programme[self.Screen]["info"] != "no" : - text = self.programme[self.Screen]["name"] + "\n" + self.programme[self.Screen]["info"] + "\n" + self.process_output - else : - text = self.programme[self.Screen]["name"] + "\n" + self.process_output - + text = self.programme[self.Screen].display() self.display_combined_im(text) def bouton_next(self): @@ -350,45 +362,17 @@ def toggle_video_stream(self): def start_process(self,num_programme): - - if self.programme[self.last_programme]["info"] != "no": - self.programme[self.last_programme]["info"] = "" - - if self.process is not None: - try: - os.killpg(os.getpgid(self.process.pid), signal.SIGKILL) - except Exception as e: - print(e) - - if (num_programme == self.last_programme): - if self.programme_actuel["type"] == "function": # les fonction on besoin d'êter rappelé pour pouvoir les arreter - self.programme_actuel["path"]() - self.last_programme = 0 # pour pouvoir lancer le programme en rapuyant sur le bouton - return # si on est sur le même programme on kill et c'est tout + if self.programme[num_programme].running: + self.programme[num_programme].kill() + + elif self.programme[num_programme].controls_car: + self.programme[self.last_programme_control].kill() + self.programme[num_programme].start() + self.last_programme_control = num_programme - if self.programme[num_programme]["info"] != "no": - self.programme[num_programme]["info"] = "(running)" - self.process_output = "" - self.last_programme = num_programme - self.programme_actuel = self.programme[num_programme] - if self.programme_actuel["type"] == "bash": - self.process = subprocess.Popen( - self.programme_actuel["path"], - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=os.setsid - ) - + else: + self.programme[num_programme].start() - elif self.programme_actuel["type"] == "python": - self.process = subprocess.Popen(["uv","run",self.programme_actuel["path"]], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - preexec_fn=os.setsid - ) - elif self.programme_actuel["type"] == "function": - self.programme_actuel["path"]() @@ -398,13 +382,7 @@ def start_process(self,num_programme): # car function #--------------------------------------------------------------------------------------------------- - def switch_remote_control(self): - if self.remote_control: - self.remote_control = False - self.programme[self.last_programme]["info"] = "" - else: - self.remote_control = True - threading.Thread(target=self.car_controle, args=(public,False,), daemon=True).start() + def main(self): self.bp_next.when_pressed = self.bouton_next diff --git a/src/HL/SshProgramme.py b/src/HL/SshProgramme.py new file mode 100644 index 00000000..b57e0c3c --- /dev/null +++ b/src/HL/SshProgramme.py @@ -0,0 +1,8 @@ +from programme import Program +from get_ip import get_ip + +class SshProgramme(Program): + def __init__(self): + self.name = "Ssh to:" + get_ip() + self.running = False + self.controls_car = False diff --git a/src/HL/programme.py b/src/HL/programme.py new file mode 100644 index 00000000..14ac4180 --- /dev/null +++ b/src/HL/programme.py @@ -0,0 +1,27 @@ +from Autotech_constant import LOGGING_LEVEL +import logging +from typing import Optional + +class Program: + name:str + controls_car:bool + running:bool + vitesse_d:Optional[float] + direction:Optional[float] + + def __init__(self): + self.logger = logging.getLogger() + self.logger.setLevel(LOGGING_LEVEL) + + def kill(): + pass + + def start(): + pass + + def display(): + if (running): + return self.name + "\n" + "(running)" + else: + return self.name + "\n" + \ No newline at end of file From 0ce59a1e22985616920626c854495a2973d57813 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 03:18:44 +0100 Subject: [PATCH 079/107] fix: fix plusiseur programme pour que cela marche --- scripts/commande_PS4.py | 6 +++--- src/HL/RemoteControl.py | 3 ++- src/HL/Serveur_mq.py | 32 ++++++++++---------------------- src/HL/SshProgramme.py | 13 +++++++++++-- src/HL/programme.py | 10 +++++----- 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 63d385cb..af43195d 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -52,7 +52,7 @@ def __init__(self): def start(self): self.running = True - self.stop = False + self.controller.stop = False self.thread = Thread( target=self.controller.listen, kwargs=dict(timeout=60), daemon=True @@ -60,7 +60,7 @@ def start(self): self.thread.start() def kill(self): - self.stop = True + self.controller.stop = True self.running = False @property @@ -74,7 +74,7 @@ def direction(self): class MyController(Controller): def __init__(self, **kwargs): - super().__init__(self, **kwargs) + super().__init__(**kwargs) self.vitesse_mms = 0 # vitesse initiale en métre par milliseconde self.direction = 0 # angle initiale des roues en degrés self.filtered = 0 diff --git a/src/HL/RemoteControl.py b/src/HL/RemoteControl.py index 6d3c0fb3..36b74241 100644 --- a/src/HL/RemoteControl.py +++ b/src/HL/RemoteControl.py @@ -1,6 +1,7 @@ from programme import Program import struct import socket +import threading class RemoteControl(Program): def __init__(self): @@ -30,7 +31,7 @@ def car_controle(self,sock): def start(self): self.running = True - threading.Thread(target=self.car_controle, args=(public,), daemon=True).start() + threading.Thread(target=self.car_controle, args=(self.public,), daemon=True).start() def kill(self): self.running = False \ No newline at end of file diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 8830cb6c..f41ad296 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -103,7 +103,7 @@ def __init__(self): #donnée des process self.process_output = "" - self.last_programme = 0 + self.last_programme_control = 0 self.process = None self.temp = None # self.programme = { @@ -155,14 +155,9 @@ def __init__(self): # } self.camera = Camera() - self.program = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] + self.programme = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] - - - #initialisation de commande - self.commande_PS4 = initialize_commande_PS4() - #donnée du lidar self.lidar = None self.rDistance = [] @@ -221,9 +216,9 @@ def display_combined_im(self,text): def Idle(self): #Enable chossing between states - if self.Screen==0 and check_ssh_connections(): + if check_ssh_connections(): self.led1.on() - self.Screen=1 + if not check_ssh_connections(): self.led1.off() @@ -265,19 +260,10 @@ def i2c_loop(self): print("lancement de l'i2c") while True: try : - - if (time.time()- self.last_cmd_time < 0.5): - data = struct.pack(' Date: Thu, 4 Dec 2025 03:30:54 +0100 Subject: [PATCH 080/107] =?UTF-8?q?fix:=20petit=20emb=C3=A9lissement=20et?= =?UTF-8?q?=20suppression=20de=20chose=20inutile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 66 +------------------------------------------- 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index f41ad296..8b5cbf48 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -57,16 +57,6 @@ #uv pip uninstall numpy # on recoit les inoformations -""" -private = context.socket(zmq.SUB) -private.bind("tcp://127.0.0.1:5555") -private.setsockopt_string(zmq.SUBSCRIBE, "") - -public = context.socket(zmq.SUB) -public.bind("tcp://0.0.0.0:5556") -public.setsockopt_string(zmq.SUBSCRIBE, "") -""" -# on envoie en udp les commandes de la ps4 private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -106,53 +96,6 @@ def __init__(self): self.last_programme_control = 0 self.process = None self.temp = None - # self.programme = { - # 0: { - # "name" : "Ssh to :\n" + self.ip, - # "type" : "", - # "path" : "", - # "info" : "no" - # }, - # 1: { - # "name" : "Auto Driving", - # "type" : "python", - # "path" : "", - # "info" : "", - # "controll_car" : "yes" - # }, - # 2: { - # "name" : "PS4 Controller", - # "type" : "function", - # "path" : lambda: toggle_commande_PS4(self.commande_PS4), - # "info" : "", - # "controll_car" : "yes" - # }, - # 3: { - # "name" : "Connect Controller", - # "type" : "bash", - # "path" : "./scripts/bluetooth_auto/bluethootconnect.sh", - # "info" : "no" - # }, - # 4: { - # "name" : "Remote control", - # "type" : "function", - # "path" : lambda: self.switch_remote_control(), - # "info" : "", - # "controll_car" : "yes" - # }, - # 5: { - # "name" : "Streaming Video", - # "type" : "function", - # "path" : lambda: self.toggle_video_stream(), - # "info" : "" - # }, - # 6: { - # "name" : "poweroff", - # "type" : "bash", - # "path" : "sudo poweroff", - # "info" : "" - # } - # } self.camera = Camera() self.programme = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] @@ -171,7 +114,7 @@ def __init__(self): #----------------------------------------------------------------------------------------------------- # affichage de l'écrans #----------------------------------------------------------------------------------------------------- - def affichage_oled(self,selected): #test + def affichage_oled(self,selected): #test non utilisé im = Image.new("1", (128, 64), "black") draw = ImageDraw.Draw(im) font = ImageFont.load_default() @@ -334,13 +277,6 @@ def lidar_update_data(self): print("pas lidar") time.sleep(1) - - def toggle_video_stream(self): - """Start continuous JPEG compressed video streaming via ZMQ.""" - try: - self.camera.toggle_stream() - except: - print("Camera Down...") #--------------------------------------------------------------------------------------------------- # Processus From 2126db6d8919c7d61fdd329e6626b58b0783ceab Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 03:34:55 +0100 Subject: [PATCH 081/107] fix: dans remote control import time --- src/HL/RemoteControl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/RemoteControl.py b/src/HL/RemoteControl.py index 36b74241..1ad9a0c4 100644 --- a/src/HL/RemoteControl.py +++ b/src/HL/RemoteControl.py @@ -2,6 +2,7 @@ import struct import socket import threading +import time class RemoteControl(Program): def __init__(self): From 1d1218b810571c88518413c52fd53a29f0072d64 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 21:09:44 +0100 Subject: [PATCH 082/107] feat : rajout d'information pour mes fonction --- README.md | 5 +++ src/HL/Serveur_mq.py | 75 +++++++++++++++++++----------------------- src/HL/SshProgramme.py | 8 +++-- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 707636aa..c1cf15f1 100755 --- a/README.md +++ b/README.md @@ -54,6 +54,11 @@ For detailed information on architecture, hardware specifics and technical choic (Note: The Wiki is currently private and reserved to INTech members) + +# some dependencies needed +libcap-dev +python3-libcamera + # License This project is distributed under the MIT License. See the Licence file for details. diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 8b5cbf48..86e1bade 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -47,17 +47,6 @@ TEXT_HEIGHT = 11 TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff -#sudo apt install libcap-dev -#sudo apt install python3-libcamera - -#sudo apt-get install libcap-dev pour lancer picamera2 -#rm -rf .venv -#uv venv --system-site-packages -#source .venv/bin/activate -#uv pip uninstall numpy - -# on recoit les inoformations - private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) private.bind(("127.0.0.1", 5555)) @@ -70,34 +59,40 @@ class Serveur(): def __init__(self): + #initialisation des différents module qui tourne tout le temps + self.camera = Camera() + self.bp_next = Button("GPIO5", bounce_time=0.1) self.bp_entre = Button("GPIO6", bounce_time=0.1) - self.length_i2c_received = 3 + self.led1 = LED("GPIO17") self.led2 = LED("GPIO27") self.buzzer = Buzzer("GPIO26") self.remote_control = False # on initialise le remote control à False - self.vitesse_d = 0 - self.vitesse_r = 0 - self.direction = 0 + self.length_i2c_received = 3 #nombre de donnée à récupéré de l'arduino (voltage lipo, voltage nimh) + + # initialisation des donnnée de la voiture + self.vitesse_d = 0 #vitesse demandé par le programme + self.direction = 0 #direction des roue + #initialisation des variable reçue de l'arduino pour débugage self.voltage_lipo = 0 self.voltage_nimh = 0 + self.vitesse_r = 0 #vitesse réel de la voiture + self.camera_reverse = True + # initialisation des commande de temps self.initial_time = time.time() self.last_cmd_time = time.time() - self.ip = get_ip() - #donnée des process self.process_output = "" self.last_programme_control = 0 self.process = None self.temp = None - self.camera = Camera() self.programme = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] @@ -111,9 +106,9 @@ def __init__(self): self.State = 0 self.scroll_offset = 3 - #----------------------------------------------------------------------------------------------------- - # affichage de l'écrans - #----------------------------------------------------------------------------------------------------- + #----------------------------------------------------------------------------------------------------- + # affichage de l'écrans + #----------------------------------------------------------------------------------------------------- def affichage_oled(self,selected): #test non utilisé im = Image.new("1", (128, 64), "black") draw = ImageDraw.Draw(im) @@ -132,7 +127,9 @@ def affichage_oled(self,selected): #test non utilisé display.bitmap((0, 0), im, fill="white") def make_voltage_im(self): - received = [self.voltage_lipo , self.voltage_nimh] # Adjust length as needed + """crée l'image de la derniére ligne qui affiche le voltage des deux batterie de la pi en temps réel""" + + received = [self.voltage_lipo , self.voltage_nimh] # filter out values below 6V and round to 2 decimal places received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" @@ -143,6 +140,7 @@ def make_voltage_im(self): return im def display_combined_im(self,text): + """ fonction qui écris sur l'écran le texte qu'on lui fourni (et remet par dessus toujours le voltage des batteries)""" im = Image.new("1", (128, 64), "black") draw = ImageDraw.Draw(im) font = ImageFont.load_default() @@ -158,7 +156,11 @@ def display_combined_im(self,text): draw.bitmap((0, 0), im, fill="white") - def Idle(self): #Enable chossing between states + def Idle(self): + """ + gére l'affichage de l'écrans en fonction des fonction en cour ou choisie. + le changement d'écran est géré par les fonction des boutons juste en dessous + """ if check_ssh_connections(): self.led1.on() @@ -170,11 +172,13 @@ def Idle(self): #Enable chossing between states self.display_combined_im(text) def bouton_next(self): + """ passe à l'écrans suivant (juste visuelle)""" self.Screen+=1 if self.Screen>=len(self.programme): self.Screen=0 def bouton_entre(self,num=None): + """séléctionne le programme afficher à l'acrans et le lance""" if num!=None: self.Screen = num self.State=self.Screen @@ -199,7 +203,7 @@ def _initialize_lidar(self): # fonction pour la communication #--------------------------------------------------------------------------------------------------- def i2c_loop(self): - """Envoie vitesse/direction régulièrement au microcontroleur.""" + """Envoie vitesse/direction régulièrement au microcontroleur. (toute les frames actuellement)""" print("lancement de l'i2c") while True: try : @@ -210,6 +214,7 @@ def i2c_loop(self): time.sleep(1) def i2c_received(self): + """récupére les informations de l'arduino""" length = self.length_i2c_received * 4 while True: data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length) @@ -224,23 +229,6 @@ def i2c_received(self): self.vitesse_r = list_valeur[2] time.sleep(0.1) - - - def car_controle(self,sock, is_private): - """ on regarde si il s'agit de lappelle pour le control interne - (is_private) ou si on veux prendre le controle depuis le pc.""" - sock.settimeout(0.1) - - while is_private or self.remote_control: - try: - data, ip = sock.recvfrom(1024) - self.vitesse_d, self.direction = struct.unpack("ff", data) - self.last_cmd_time = time.time() - except socket.timeout: - continue - - - def envoie_donnee(self, socket): """ on regarde si il s'agit de lappelle pour le control interne (is_private) ou si on veux prendre le controle depuis le pc.""" @@ -267,6 +255,7 @@ def envoie_donnee(self, socket): socket.send_json({"Error" : "not understand"}) def lidar_update_data(self): + """donnée du lidar""" self._initialize_lidar() while True: try : @@ -284,6 +273,9 @@ def lidar_update_data(self): def start_process(self,num_programme): + """lance le porgramme référencé avec son numéro: + si il sagit d'un programme qui controle la voiture il kill lancient programme qui controlé, + sinon le programme est lancé ou tué celon si il était déjà lancé ou tué avant""" if self.programme[num_programme].running: self.programme[num_programme].kill() if self.programme[num_programme].controls_car: @@ -314,7 +306,6 @@ def main(self): threading.Thread(target=self.i2c_loop, daemon=True).start() threading.Thread(target=self.i2c_received, daemon=True).start() - threading.Thread(target=self.car_controle, args=(private,True,), daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() threading.Thread(target=self.lidar_update_data, daemon=True).start() diff --git a/src/HL/SshProgramme.py b/src/HL/SshProgramme.py index 0a0cccf7..b34688a2 100644 --- a/src/HL/SshProgramme.py +++ b/src/HL/SshProgramme.py @@ -11,7 +11,9 @@ def __init__(self): self.direction = 0 def display(self): + text = self.name if check_ssh_connections(): - return self.name + "\n connecté" - else: - return self.name \ No newline at end of file + text+= "\n connecté" + if self.running: + text+= "\n Voiture en stand by" + return text \ No newline at end of file From f3358430a2ef7c872bf9b0a9db6f05e2882cf51f Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 21:30:12 +0100 Subject: [PATCH 083/107] =?UTF-8?q?fix=20:=20rajout=20de=20la=20possibilit?= =?UTF-8?q?=C3=A9=20de=20mettre=20la=20voiture=20en=20stand=20by.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/SshProgramme.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/HL/SshProgramme.py b/src/HL/SshProgramme.py index b34688a2..5115ade2 100644 --- a/src/HL/SshProgramme.py +++ b/src/HL/SshProgramme.py @@ -4,12 +4,19 @@ class SshProgramme(Program): def __init__(self): self.name = "Ssh to:" + get_ip() - self.running = False + self.running = True self.controls_car = True self.vitesse_d = 0 self.direction = 0 + + def start(self): + self.running = True + + def stop(self): + self.running = False + def display(self): text = self.name if check_ssh_connections(): From c3212b67da86f9e43b04c81ac9a76244a8b77315 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Thu, 4 Dec 2025 22:04:18 +0100 Subject: [PATCH 084/107] =?UTF-8?q?feat=20:=20rajout=20de=20commantaire=20?= =?UTF-8?q?pour=20plus=20de=20visibilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/commande_PS4.py | 15 +++++++-------- src/HL/Autotech_constant.py | 8 ++++---- src/HL/RemoteControl.py | 3 ++- src/HL/Serveur_mq.py | 5 +---- src/HL/SshProgramme.py | 3 ++- src/HL/programme.py | 1 + 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index af43195d..c2f52074 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -2,8 +2,8 @@ import time import os from threading import Thread -from src.HL.Autotech_constant import SOCKET_ADRESS from programme import Program +from src.HL.Autotech_constant import MAX_ANGLE ################################################### #Intialisation du protocole zmq ################################################## @@ -12,8 +12,9 @@ def envoie_donnee(Voiture): #si utilisation de la voiture directement print("lancement de l'i2c") import smbus import struct + from src.HL.Autotech_constant import SLAVE_ADDRESS + bus = smbus.SMBus(1) - SLAVE_ADDRESS = 0x08 while True: try : data = struct.pack(' Date: Thu, 11 Dec 2025 15:42:18 +0100 Subject: [PATCH 085/107] feat : rajout Car pour qu'il soit utiliser dans la nouvelle structure --- src/HL/Car.py | 85 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/HL/Car.py b/src/HL/Car.py index 09b45d85..d675fb33 100644 --- a/src/HL/Car.py +++ b/src/HL/Car.py @@ -8,11 +8,7 @@ import smbus # type: ignore #ignore the module could not be resolved error because it is a linux only module import struct from masterI2C import write_vitesse_direction - -SLAVE_ADDRESS = 0x08 -# Create an SMBus instance -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 - +from threading import Thread # Import constants from HL.Autotech_constant to share them between files and ease of use from Autotech_constant import MAX_SOFT_SPEED, MAX_ANGLE, CRASH_DIST, MODEL_PATH, SOCKET_ADRESS, REAR_BACKUP_DIST, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET @@ -22,10 +18,12 @@ from ToF import ToF class Car: - def __init__(self, driver): + def __init__(self, driver, camera, lidar): """Initialize the car's components.""" - self.vitesse_milimetres_s = 0 # Speed in millimeters per second - self.angle_degre = 0 # Steering angle in degrees + self.vitesse_d = 0 # Speed in millimeters per second + self.direction_d = 0 # Steering angle in degrees + self.camera = camera + self.lidar = lidar def _initialize_ai(): """Initialize the AI session.""" @@ -73,9 +71,9 @@ def _initialize_tof(): _initialize_ai() # Initialize Lidar - _initialize_lidar() + #_initialize_lidar() - _initialize_camera() + #_initialize_camera() _initialize_tof() @@ -85,22 +83,11 @@ def _initialize_tof(): log.info("Car initialization complete") - def set_vitesse_m_s(self, vitesse_m_s): - """Set the car's speed in meters per second.""" - self.vitesse_milimetres_s = int(vitesse_m_s * 1000) # Convert to millimeters per second - write_vitesse_direction(self.vitesse_milimetres_s,self.angle_degre) #take the vitesse in milimeters per second - - def set_direction_degre(self, n_angle_degre): - """Set the car's steering angle in degrees.""" - self.angle_degre = n_angle_degre - write_vitesse_direction(self.vitesse_milimetres_s, self.angle_degre) #take the angle in degrees - - def stop(self): - self.vitesse_milimetres_s = 0 - self.angle_degre = 0 - write_vitesse_direction(self.vitesse_milimetres_s, self.angle_degre) #stop the car + self.vitesse_d = 0 + self.direction_d = 0 + write_vitesse_direction(self.vitesse_d, self.direction_d) #stop the car log.info("Arrêt du moteur") self.lidar.stop() @@ -113,7 +100,7 @@ def has_Crashed(self): # min_index = self.lidar.rDistance.index(min(small_distances)) while self.tof.get_distance() < REAR_BACKUP_DIST: log.info(f"Obstacle arriere détecté {self.tof.get_distance()}") - self.set_vitesse_m_s(0) + self.vitesse_d = 0 time.sleep(0.1) return True return False @@ -122,9 +109,9 @@ def turn_around(self): """Turn the car around.""" log.info("Turning around") - self.set_vitesse_m_s(0) - self.set_direction_degre(MAX_ANGLE) - self.set_vitesse_m_s(-2) #blocing call + self.vitesse_d = 0 + self.direction_d = MAX_ANGLE + self.vitesse_d = -2 #blocing call time.sleep(1.8) # Wait for the car to turn around if self.camera.is_running_in_reversed(): self.turn_around() @@ -138,10 +125,9 @@ def main(self): lidar_data_ai= (lidar_data-0.5)*( LIDAR_DATA_OFFSET + LIDAR_DATA_AMPLITUDE * np.exp(-1/2*((np.arange(1080) - 135) / LIDAR_DATA_SIGMA**2)) ) #convertir en mètre et ajouter un bruit gaussien #On traffique les données fournit a l'IA - angle, vitesse = self.driving(lidar_data_ai) #l'ai prend des distance en mètre et non en mm + self.direction_d, self.vitesse_d = self.driving(lidar_data_ai) #l'ai prend des distance en mètre et non en mm log.debug(f"Min Lidar: {min(lidar_data)}, Max Lidar: {max(lidar_data)}") - self.set_direction_degre(angle) - self.set_vitesse_m_s(vitesse) + if self.camera.is_running_in_reversed(): self.reverse_count += 1 else: @@ -166,10 +152,39 @@ def main(self): if color == 1: log.info("Obstacle vert détecté") angle= -color*MAX_ANGLE - self.set_vitesse_m_s(-2) - self.set_direction_degre(angle) + self.vitesse_d = -2 + self.direction_d = angle + + +class Ai_Programme(): + def __init__(self, Camera, Lidar): + self.ia_voiture = Driver(128,128) + self.GR86 = Car(self.ia_voiture, Camera, Lidar) + self.running = False + + @property + def vitesse_d(self): + return self.GR86.vitesse_d + + @property + def direction_d(self): + return self.GR86.direction_d + + def run(self): + while self.running: + self.GR86.main() + + def start(self): + self.running = True + Thread( + target=self.run, daemon=True + ).start() + + def stop(self): + self.running = False + if __name__ == '__main__': Format= '%(asctime)s:%(name)s:%(levelname)s:%(message)s' @@ -180,7 +195,9 @@ def main(self): bp2 = Button("GPIO6") try: Schumacher = Driver(128, 128) - GR86 = Car(Schumacher) + GR86 = Car(Schumacher,None,None) + GR86._initialize_camera() + GR86._initialize_lidar() log.info("Initialisation terminée") if input("Appuyez sur D pour démarrer ou tout autre touche pour quitter") in ("D", "d") or bp2.is_pressed: log.info("Depart") From 863741d3e7294ba185bee5743b04008ded662d42 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 16 Dec 2025 16:02:31 +0100 Subject: [PATCH 086/107] test: rajout d'un programme pour les module externe --- src/HL/Serveur_mq.py | 20 +++++++--- src/HL/module_initialisation.py | 71 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 src/HL/module_initialisation.py diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 96c27351..83d679e6 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -30,6 +30,7 @@ from RemoteControl import RemoteControl from Poweroff import Poweroff from Camera import ProgramStreamCamera +from module_initialisation import Initialisation serial = i2c(port=1, address=0x3C) device = ssd1306(serial) @@ -90,13 +91,22 @@ def __init__(self): self.process = None self.temp = None - self.programme = [SshProgramme(), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] + self.initialisation_module = Initialisation(Camera,lidar,tof) + + @property + def camera(self): + return self.initialisation_module.camera + + @property + def lidar(self): + return self.initialisation_module.lidar + + @property + def tof(): + return self.initialisation_module.tof - #donnée du lidar - self.lidar = None - self.rDistance = [] - self.xTheta = 0 + self.programme = [SshProgramme(), self.initialisation_module, PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self.camera), Poweroff()] # donnée de l'écran self.Screen = 0 diff --git a/src/HL/module_initialisation.py b/src/HL/module_initialisation.py new file mode 100644 index 00000000..9f8ef7e9 --- /dev/null +++ b/src/HL/module_initialisation.py @@ -0,0 +1,71 @@ + +from programme import Program + + +class Initialisation(Program): + def __init__(self, camera, lidar, tof): + self.name = "Initialisation:" + self.camera = None + self.lidar = None + self.tof = None + self.camera_init = 0 + self.lidar_init = 0 + self.tof_init = 0 + self.error = "" + threading.Thread(target=self.init_camera, args=(camera,), daemon=True).start() + threading.Thread(target=self.init_lidar, args=(lidar,), daemon=True).start() + threading.Thread(target=self.init_tof, args=(tof,), daemon=True).start() + + + def init_camera(self,camera): + try: + self.camera = camera() + self.camera_init = 1 + except Exception as e: + self.camera_init = 2 + self.error += str(e) + + def init_lidar(self,lidar): + try: + self.lidar = lidar() + self.lidar_init = 1 + except Exception as e: + self.lidar_init = 2 + self.error += str(e) + + def init_tof(self,tof): + try: + self.tof = tof() + self.tof_init = 1 + except Exception as e: + self.tof_init = 2 + self.error += str(e) + + def display(self): + text = self.name + + text+= "camera: " + if self.camera_init == 0: + text += "(en cour)" + elif self.camera_init == 1: + text += "près." + elif self.camera_init == 2: + text += "error" + + text+= "\nlidar: " + if self.lidar_init == 0: + text += "(en cour)" + elif self.lidar_init == 1: + text += "près." + elif self.lidar_init == 2: + text += "error" + + text+= "\ntof:" + if self.tof_init == 0: + text += "(en cour)" + elif self.tof_init == 1: + text += "près." + elif self.tof_init == 2: + text += "error" + + return text \ No newline at end of file From f76afa722c24d8c81399ac83ac552fabbcd4e9ef Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 16 Dec 2025 17:44:39 +0100 Subject: [PATCH 087/107] =?UTF-8?q?feat:=20uniformisation=20direction=5Fd?= =?UTF-8?q?=20et=20rajout=20d'un=20module=20pour=20initialiser=20les=20cap?= =?UTF-8?q?teur=20de=20fa=C3=A7ons=20=C3=A0=20debug=20facilement,=20avec?= =?UTF-8?q?=20changement=20pour=20que=20le=20tout=20marche=20avec=20la=20n?= =?UTF-8?q?ouvelle=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/commande_PS4.py | 12 ++-- src/HL/Camera.py | 15 +++- src/HL/Car.py | 117 ++++++++++++++++---------------- src/HL/Driver.py | 18 ++++- src/HL/RemoteControl.py | 2 +- src/HL/Serveur_mq.py | 60 ++++++---------- src/HL/SshProgramme.py | 2 +- src/HL/module_initialisation.py | 18 +++-- src/HL/programme.py | 2 +- 9 files changed, 129 insertions(+), 117 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index c2f52074..0342d9a0 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -17,7 +17,7 @@ def envoie_donnee(Voiture): #si utilisation de la voiture directement bus = smbus.SMBus(1) while True: try : - data = struct.pack(' Date: Tue, 16 Dec 2025 17:51:28 +0100 Subject: [PATCH 088/107] fix: petit soucis --- src/HL/RemoteControl.py | 2 +- src/HL/SshProgramme.py | 2 +- uv.lock | 1526 +++++++++++++++++++++------------------ 3 files changed, 813 insertions(+), 717 deletions(-) diff --git a/src/HL/RemoteControl.py b/src/HL/RemoteControl.py index 4b45d3d8..91e2c628 100644 --- a/src/HL/RemoteControl.py +++ b/src/HL/RemoteControl.py @@ -26,7 +26,7 @@ def car_controle(self,sock): while self.running: try: data, ip = sock.recvfrom(1024) - self.vitesse_d, self.direction = struct.unpack("ff", data) + self.vitesse_d, self.direction_d = struct.unpack("ff", data) except socket.timeout: continue diff --git a/src/HL/SshProgramme.py b/src/HL/SshProgramme.py index 47ce45fe..dc43ec81 100644 --- a/src/HL/SshProgramme.py +++ b/src/HL/SshProgramme.py @@ -9,7 +9,7 @@ def __init__(self): self.controls_car = True self.vitesse_d = 0 - self.direction = 0 + self.direction_d = 0 def start(self): diff --git a/uv.lock b/uv.lock index 3efd714e..4b5d9e52 100644 --- a/uv.lock +++ b/uv.lock @@ -2,23 +2,15 @@ version = 1 revision = 3 requires-python = ">=3.10" resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.13'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", + "python_full_version < '3.11'", ] [[package]] name = "adafruit-blinka" -version = "8.63.0" +version = "8.68.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-circuitpython-typing" }, @@ -29,52 +21,52 @@ dependencies = [ { name = "sysv-ipc", marker = "platform_machine != 'mips' and sys_platform == 'linux'" }, { name = "toml", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/7b/8d78afacf9cade7149c57fd8f120e822b37897fbb47455db87b86098982e/adafruit_blinka-8.63.0.tar.gz", hash = "sha256:26345648a1d539092983b6702bae1c6e2641bc725c8704fab316595ca1224ba5", size = 267817, upload-time = "2025-08-16T23:09:58.819Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/ca/362177fd0830201fd2a9ae34cecdd5593c9fa9d9d3bc81a6941a54cbe221/adafruit_blinka-8.68.0.tar.gz", hash = "sha256:7411be4c88ac56412b0fa2f1154bfbe5f93ad3010591a5dc8d7f3bc13ea7bbd8", size = 609425, upload-time = "2025-11-20T21:20:24.739Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/47/2ae3f2d21155a4d03a9865eda49d931fd8e86325164d1d9f80559a31113f/adafruit_blinka-8.63.0-py3-none-any.whl", hash = "sha256:00e386d13e104817680b88a6d9207623e35a5a0b23974e604541b90387bb1a6c", size = 396931, upload-time = "2025-08-16T23:09:57.016Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/f82fc7dbfe6dc4d1bb6e6dd99b48b5ad4df2acee56bb5e560203108a60a3/adafruit_blinka-8.68.0-py3-none-any.whl", hash = "sha256:6a1f60fa03312da0bcac9f282930d3a69e07486ef968d30a5f518ebe13a04e7a", size = 741725, upload-time = "2025-11-20T21:20:23.045Z" }, ] [[package]] name = "adafruit-circuitpython-busdevice" -version = "5.2.13" +version = "5.2.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-blinka" }, { name = "adafruit-circuitpython-typing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/34/de/6c974f577169789d5105baba5f9e7d3ac00fdc467bc21673382a5d9e41f4/adafruit_circuitpython_busdevice-5.2.13.tar.gz", hash = "sha256:8dbe511f08a347527652f494b55d793c91dc077e01666824b691ae96a05ff2e6", size = 24165, upload-time = "2025-06-17T16:35:35.483Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/70/2bb69cf3e79fc1bda7b111bcf9f90ff25ac705960eff6bd1375ffad754ff/adafruit_circuitpython_busdevice-5.2.14.tar.gz", hash = "sha256:377f4d9c6b7ac256a0c686fe3d88bb2d10873cec992ff7805c8719a474e92127", size = 24468, upload-time = "2025-10-20T20:37:13.497Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/4f/e9fad422c8e85213f3b9e2d0e58342c67bf03c50f889661adef12f07495f/adafruit_circuitpython_busdevice-5.2.13-py3-none-any.whl", hash = "sha256:de90f8cd9cc7f8815840f04b6a24c9aa5ec355b368934c7373e219a1c740ea97", size = 7501, upload-time = "2025-06-17T16:35:34.738Z" }, + { url = "https://files.pythonhosted.org/packages/f6/50/3fe9da5d3a66a05130ee5db64b5451cd2973f7f5981f80a72ce349ea1bdc/adafruit_circuitpython_busdevice-5.2.14-py3-none-any.whl", hash = "sha256:e7d049a2dc6a3fc9245e154d66725efeb190a61e7d192fbc8f96f3b76fe1fc77", size = 7501, upload-time = "2025-10-20T20:37:12.675Z" }, ] [[package]] name = "adafruit-circuitpython-connectionmanager" -version = "3.1.5" +version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-blinka" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/24/22c00c99d0597e703dd73b5f042854620a5db2424c03606e93d3f4e2e5a8/adafruit_circuitpython_connectionmanager-3.1.5.tar.gz", hash = "sha256:fc037d7ff81cf7bab7653f2810ed8c65fe228e7d51ca7a630724b412d6c77226", size = 33632, upload-time = "2025-06-17T16:33:46.705Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/82/69ca5ef604b0513a5f85a583d255b2d0c48042592842dfbc955b610cf3b6/adafruit_circuitpython_connectionmanager-3.1.6.tar.gz", hash = "sha256:daa41f7675533fbb451c0f522c894911dd003f67b26f0e7be832f2e240ba28b4", size = 33798, upload-time = "2025-10-20T20:38:47.369Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/37/09acb7aed34a1c72465884d071a9dbad112994a3f416ad904e4acfd83bc8/adafruit_circuitpython_connectionmanager-3.1.5-py3-none-any.whl", hash = "sha256:cea077efe79eaefcd8fc0d6649dbcc6cb0765f71a08bd944fb163043b18cd094", size = 7767, upload-time = "2025-06-17T16:33:45.931Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/174bff10a4ff6f74973ee6da43e7b715b07e34426cf4e71d625a7f96e1e5/adafruit_circuitpython_connectionmanager-3.1.6-py3-none-any.whl", hash = "sha256:83c7eafa294fc6e889076d1ba8a7ff902e29d062977d3602078b1594868b7042", size = 7768, upload-time = "2025-10-20T20:38:45.959Z" }, ] [[package]] name = "adafruit-circuitpython-requests" -version = "4.1.13" +version = "4.1.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-blinka" }, { name = "adafruit-circuitpython-connectionmanager" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/5c/d17ff26270289c11ea787a73a922c1a9d85d8dea67e8d2fad1e36b181bc1/adafruit_circuitpython_requests-4.1.13.tar.gz", hash = "sha256:a63fa4eb5824f1f458030da6f44a060d28c01570ffa48569b992abe8e477a1d6", size = 67276, upload-time = "2025-06-17T16:39:26.862Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/ec54c3e224a012d620997604fdd6abdbff1b945df3b4aef43d780fd1d5c3/adafruit_circuitpython_requests-4.1.15.tar.gz", hash = "sha256:409cb1c9304a0ce0a4b2f64d572400007849f6972f92a4b08ebfe35a532761e7", size = 67841, upload-time = "2025-11-03T21:32:59.201Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/53/c59ee1edf3305fc5a66ea62db50918ce841a5f6bf7b94d273625a9364f7d/adafruit_circuitpython_requests-4.1.13-py3-none-any.whl", hash = "sha256:2d5af59a96dca033033fcc8c17829c3fb28ed8c36a95fe1093c463f5841bc5a5", size = 10880, upload-time = "2025-06-17T16:39:25.909Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/76a9805ff64d84a39463ac6eeb9c780becfc8ff58a93c5ace9244d56e442/adafruit_circuitpython_requests-4.1.15-py3-none-any.whl", hash = "sha256:62c6e44d23e8dfdc24f1f33464953019a9d88853b29fa471ac00200d4fa3e8ff", size = 10882, upload-time = "2025-11-03T21:32:57.915Z" }, ] [[package]] name = "adafruit-circuitpython-typing" -version = "1.12.1" +version = "1.12.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-blinka" }, @@ -82,22 +74,22 @@ dependencies = [ { name = "adafruit-circuitpython-requests" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/d6/cb9a842dd89afcc53d21327cef5d3ee0149cfd3d90677c9dd68274b0bfae/adafruit_circuitpython_typing-1.12.1.tar.gz", hash = "sha256:e4b06e07cb385dc098574f2479cd77d07e0a06987c814eab33b9f525ac83a935", size = 26001, upload-time = "2025-05-30T17:46:34.679Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/a2/40a3440aed2375371507af668570b68523ee01db9c25c47ce5a05883170e/adafruit_circuitpython_typing-1.12.3.tar.gz", hash = "sha256:63f196f834e47842bcd4cf8c37aaa0c61e1aeb5d07f056c875fc3016cda91a12", size = 25603, upload-time = "2025-10-27T18:17:38.56Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/d9/fe145e99e1251a0dcdace585477875eef8db915f04647197aa3aa50c51d6/adafruit_circuitpython_typing-1.12.1-py3-none-any.whl", hash = "sha256:f1e511f48a76cb4467050db9334fed6761cc1f05921e9edddce7fd3a0b69b459", size = 11627, upload-time = "2025-05-30T17:46:33.322Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a1/578a03ba2bce0809b4e30974b47958963c9efe67b9fe74e7dbcdbbd45318/adafruit_circuitpython_typing-1.12.3-py3-none-any.whl", hash = "sha256:f6d0a02150e1e4efb5a2c2945b88d948809fdb465875f39947108b8467c986d9", size = 11014, upload-time = "2025-10-27T18:17:37.771Z" }, ] [[package]] name = "adafruit-circuitpython-vl53l0x" -version = "3.6.16" +version = "3.6.17" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-blinka" }, { name = "adafruit-circuitpython-busdevice" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/fa/d4208db4979c770a13d99c5bb6fa415c5e51b126334dc6441757eb55355c/adafruit_circuitpython_vl53l0x-3.6.16.tar.gz", hash = "sha256:f381f9b7a3d558172e91b79ede6b9effd8d3816ddbf743b478debc473215ea63", size = 30214, upload-time = "2025-06-17T16:31:47.408Z" } +sdist = { url = "https://files.pythonhosted.org/packages/26/bc/713feada2e87e9eb7297443de72be90eced2fc6e49887330fe95b55eda97/adafruit_circuitpython_vl53l0x-3.6.17.tar.gz", hash = "sha256:46ef9d4474a57498eebf0a0a4f2238e0e9a81cb0ccfd3dce94c5c8843153a429", size = 30384, upload-time = "2025-10-20T20:34:16.689Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/f3/8d024f3ed932466b836f77ced4d118105e9f00f8206370f792dcecbf1ba1/adafruit_circuitpython_vl53l0x-3.6.16-py3-none-any.whl", hash = "sha256:496b6afd077b9ed8e68d432efc252413f477528606de81871c9fbd68ccc863eb", size = 9777, upload-time = "2025-06-17T16:31:46.669Z" }, + { url = "https://files.pythonhosted.org/packages/33/22/0b5248484832260612a5d6a71adc2efa92d1efb87d07d05a7ff5761db9e0/adafruit_circuitpython_vl53l0x-3.6.17-py3-none-any.whl", hash = "sha256:03fabd87f912695acaf56fdde7bbc4c4426306af1c6b531a3e96771deaa418d8", size = 9779, upload-time = "2025-10-20T20:34:15.53Z" }, ] [[package]] @@ -106,16 +98,17 @@ version = "1.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "adafruit-pureio" }, + { name = "spidev" }, ] sdist = { url = "https://files.pythonhosted.org/packages/db/1c/2dc8a674514219f287fa344e44cadfd77b3e2878d6ff602a8c2149b50dd8/Adafruit_GPIO-1.0.3.tar.gz", hash = "sha256:d6465b92c866c51ca8f3bc1e8f2ec36f5ccdb46d0fd54101c1109756d4a2dcd0", size = 24522, upload-time = "2017-06-06T18:44:52.234Z" } [[package]] name = "adafruit-platformdetect" -version = "3.82.0" +version = "3.85.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/68/86/85237b1fd7c1052335a56b9b77179e0f2a5200d0cf747dad08f1963c3cc9/adafruit_platformdetect-3.82.0.tar.gz", hash = "sha256:0bf7ac7ba7b3c83169fb789fa1babf0e51eccf8834c2b067b960a86baf6a6188", size = 48866, upload-time = "2025-08-15T22:46:31.467Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/b5/c454d998188ea45898ada67dd302da4f138b7fc41f9c31f7aaf8b7a28cf7/adafruit_platformdetect-3.85.0.tar.gz", hash = "sha256:58350aa93dd166c4b67ba3c947b07a2d7320d14e65b92e5873fdf64d03e3f93d", size = 49223, upload-time = "2025-11-20T21:18:19.961Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/8f/8e096f8dc9cfb0221e1c0850fdeeeff32be309f05be8e6e0c9d2f160262b/adafruit_platformdetect-3.82.0-py3-none-any.whl", hash = "sha256:2282caf9464db56584c834e7de90df62d636c0d172f1c9638ce534b080840bdd", size = 26368, upload-time = "2025-08-15T22:46:30.16Z" }, + { url = "https://files.pythonhosted.org/packages/10/f2/f6e18704dad5a90f8c67cbe8c9436348a58916de3d640237908963316171/adafruit_platformdetect-3.85.0-py3-none-any.whl", hash = "sha256:eebf86b15a7f7a5dfdb811ee0f124a0e3bb0af900f0a900728ed7dedffe1af5d", size = 26669, upload-time = "2025-11-20T21:18:18.877Z" }, ] [[package]] @@ -198,6 +191,7 @@ requires-dist = [ { name = "onnxruntime", marker = "extra == 'rpi'", specifier = ">=1.8.0" }, { name = "onnxruntime", marker = "extra == 'simu'", specifier = ">=1.8.0" }, { name = "opencv-python", marker = "extra == 'rpi'", specifier = ">=4.12.0.88" }, + { name = "psutil", extras = ["simu"], marker = "extra == 'simu'", specifier = ">=7.1.3" }, { name = "pyps4controller", marker = "extra == 'rpi'", specifier = ">=1.2.0" }, { name = "rpi-gpio", marker = "extra == 'rpi'", specifier = ">=0.7.1" }, { name = "rpi-hardware-pwm", marker = "extra == 'rpi'", specifier = ">=0.1.0" }, @@ -221,15 +215,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.13.4" +version = "4.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, ] [[package]] @@ -246,60 +240,60 @@ wheels = [ [[package]] name = "cbor2" -version = "5.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/89/01df16cdc9c60c07956756c90fe92c684021003079e358a78e213bce45a2/cbor2-5.7.0.tar.gz", hash = "sha256:3f6d843f4db4d0ec501c46453c22a4fbebb1abfb5b740e1bcab34c615cd7406b", size = 102374, upload-time = "2025-08-14T08:59:47.294Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/94/92870469f92b53f7d18a6a6def540ecd9deec0cc25448b0d28b1847a7820/cbor2-5.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:305edac16524df843d53ba086bc194c0975388e755ed177eb84e0324e3d705ec", size = 67903, upload-time = "2025-08-14T08:58:37.343Z" }, - { url = "https://files.pythonhosted.org/packages/ea/cd/c6bbf2c11f48f08cbbd31647ce2b6b081f25e4723d5260fde0a6520a6e2f/cbor2-5.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e00d7250e528a9a1bfd3b294799bdae96c158f72d95be58a3fbf97dab2467bbe", size = 68780, upload-time = "2025-08-14T08:58:39.004Z" }, - { url = "https://files.pythonhosted.org/packages/7f/b7/17fe6e502b9884f3a7bdf6e9331688e290a546110dd14575aa09527b238f/cbor2-5.7.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b6e229b36147051ea1063ba0cd6225bfe6b5398ca0ac7b33fa91407ca75081", size = 254198, upload-time = "2025-08-14T08:58:40.293Z" }, - { url = "https://files.pythonhosted.org/packages/fd/fb/6cc1dd51beb35f899f9f6621fd0df9ec733e1f4c27f334212107f7a05822/cbor2-5.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:06f8e9d8fa6d0ed7b8a81f4613a60e740be9bd5087de620e3b64007832dfd815", size = 247202, upload-time = "2025-08-14T08:58:42.101Z" }, - { url = "https://files.pythonhosted.org/packages/34/2d/e51cd823cb918eed3180bbe0169955ccefa03817c0e4788024e9e56d3657/cbor2-5.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90c1236e5bfad19493183f9a9ecd3705e3ad3eb02fce6d6381c12ece86147b15", size = 250001, upload-time = "2025-08-14T08:58:43.82Z" }, - { url = "https://files.pythonhosted.org/packages/de/45/79a0320a4562537df3e589526d636963a06a95a66d7b6c366bdc8d9b3755/cbor2-5.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:afc6c6611b7529136ea4a04cf8711786640b687859c9688ae172726c305a83a1", size = 243743, upload-time = "2025-08-14T08:58:45.618Z" }, - { url = "https://files.pythonhosted.org/packages/9b/6f/73baf2ba006fb297c7d022858352ae393ee3837be2d7cfa01b6d2519492b/cbor2-5.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:be635795908d59f46303ab266fc6f3aa6543c742fa112fd1cd2e5307b91c6de4", size = 68045, upload-time = "2025-08-14T08:58:48.447Z" }, - { url = "https://files.pythonhosted.org/packages/40/87/0c7c8d27738e8d7dca49dfb4092ef7fdfdec7ca64f27e344b79d8a80bd92/cbor2-5.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:16a21233f11874b7067b136cb2910333b36c1dee455a42a7c8473a104753cf4a", size = 63963, upload-time = "2025-08-14T08:58:49.563Z" }, - { url = "https://files.pythonhosted.org/packages/45/a4/97c1b5eaf28129543ae6f90b9afc244241f5bb1701a2cf9368a2de9eb258/cbor2-5.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73532e725501915f95d589500e0a11813c9a3fd735d3cdb6c4dd320e6a2f12e1", size = 67895, upload-time = "2025-08-14T08:58:50.949Z" }, - { url = "https://files.pythonhosted.org/packages/91/60/cb2fa00871e94e75d9b84f4edd173b6644af080333c00712e8e31bd201fe/cbor2-5.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b785d954879e3800a074efa45c882a1cc6459476ab0d354c74e1dca92b17ede3", size = 68783, upload-time = "2025-08-14T08:58:52.456Z" }, - { url = "https://files.pythonhosted.org/packages/6d/52/6092e45a6b164d22bc2828aa14f422fbcf5af4bd9201a3e27b62b512f828/cbor2-5.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fc1005b412ace94bbf905a8c4214e639557568551d9b5474645789e976e91e4", size = 261081, upload-time = "2025-08-14T08:58:53.747Z" }, - { url = "https://files.pythonhosted.org/packages/0f/12/9eef73bcfcdd110df7e585f8034399d1cf2006dc7576487e0509ba50e4f8/cbor2-5.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d981d691dd721dd712fc824d04a01347955a206107fbee1d75803fa58de172c7", size = 254132, upload-time = "2025-08-14T08:58:55.465Z" }, - { url = "https://files.pythonhosted.org/packages/8c/e1/00bc92353ecacef0b8eaba285168ca517c18539c12ddebe06a9bbab03e47/cbor2-5.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b3b9730928163d02e7f1267e48a39ed75560ff3e56cdc6768d670d3e96028623", size = 256825, upload-time = "2025-08-14T08:58:57.239Z" }, - { url = "https://files.pythonhosted.org/packages/25/01/454c93f360c404a3e6531ce0e2e4cc5818c5746a10b1cb295b6abd3057cd/cbor2-5.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:01cc4d840943b4c2e468b8560830235d044a8cb45e5d66ba3ae933c3e21b8d49", size = 250639, upload-time = "2025-08-14T08:58:58.594Z" }, - { url = "https://files.pythonhosted.org/packages/94/1a/87be8d39d934810b095024bd22017c679abd51d89cb62d179b89327f491e/cbor2-5.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:6abe31e742ccf966778d77ce99d7c6136ca0f8424446dfdabcc3491f015e84d4", size = 68085, upload-time = "2025-08-14T08:59:00.045Z" }, - { url = "https://files.pythonhosted.org/packages/52/00/dce08a1549e2a4008cecb0069e8d8de45779f60852aca12a5e7d0039ce41/cbor2-5.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:c48dff8f6aacd76fc0680c48ef35e5912e3d758a9f41305a35e847f382b60eea", size = 63969, upload-time = "2025-08-14T08:59:01.187Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b1/d54c41b1bc71b8dea0bad3409d2a497df35f7b5ae5db70c1cc9ebc8d556d/cbor2-5.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7ad36f0537b75c1aa2c7a462cbdbeec5e8ba02802ea985e0b9fe5deee3b946f4", size = 69020, upload-time = "2025-08-14T08:59:02.276Z" }, - { url = "https://files.pythonhosted.org/packages/f4/e0/45368d5d78b520caaa9ca5a09f55365bc9933d43bce978a528922654ca9f/cbor2-5.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5fc9b335cf28e63d9eed4ae03d1e8f90f1a6b287cabc8d29bfddf73fa70643e9", size = 68950, upload-time = "2025-08-14T08:59:03.882Z" }, - { url = "https://files.pythonhosted.org/packages/1e/6a/9aed5b716407c1d48425ba55c6022a01a9abdbf58a691f50416461fa371d/cbor2-5.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16bea83598a1eeedbd50c2e9fdf3685bae78ca9d9ec8cd8010777db14a315578", size = 285685, upload-time = "2025-08-14T08:59:05.165Z" }, - { url = "https://files.pythonhosted.org/packages/a8/6e/3499eaa2b858c7695a447b6311303f06ffc90fc2c45851337121661f1f5c/cbor2-5.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e837825a16e60ace6e284095aa9fbe504bf87a8f4494bf7d95931e37fb01a70", size = 284948, upload-time = "2025-08-14T08:59:06.64Z" }, - { url = "https://files.pythonhosted.org/packages/d1/3e/ae67866ef65717665e0acf2873d466c5d4a1d965b0d0348f2269b73f28fb/cbor2-5.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:27396c5e275ff7c7cd87fe8aaadf781e6194903921f250934af7c86d5efec82e", size = 276375, upload-time = "2025-08-14T08:59:08.845Z" }, - { url = "https://files.pythonhosted.org/packages/b6/3d/2f8e9671111661dd571de206344ecd7706f6d458aab191e06834c89aa58e/cbor2-5.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c84bfef78c4e9c81eb0a10cec340222ba4e39498a63fc2e3d5f982a3f4efa4a7", size = 277680, upload-time = "2025-08-14T08:59:10.292Z" }, - { url = "https://files.pythonhosted.org/packages/85/03/27a9fefa4e084c1129d7180727791a166629fdae39e0609508401d322626/cbor2-5.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:f64270a24aaadb15dd31cbd64a98d99fca8e0398a65b1570ba07f3c259eb5516", size = 68354, upload-time = "2025-08-14T08:59:11.561Z" }, - { url = "https://files.pythonhosted.org/packages/25/d9/b856d078696542a0d7486d1ece5c936e937bebe5b114674db18d76feb131/cbor2-5.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:73ef321d7b580f08c9fadc41c3d2a218aa3f01e163be9793c6969aadee07f57a", size = 63896, upload-time = "2025-08-14T08:59:12.977Z" }, - { url = "https://files.pythonhosted.org/packages/5c/2f/25da2b08f7a3d7b3f72e678a373092619821ab706f3f720d29e567a426df/cbor2-5.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7654e77b7f6be029fb37a074b175483a4a8ae3fe5e2a91008926625aa91aef2c", size = 69046, upload-time = "2025-08-14T08:59:14.123Z" }, - { url = "https://files.pythonhosted.org/packages/4b/b5/d324166a5a1feed61aeb32fed70182306796b67cedaf65c91671c8674ea2/cbor2-5.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9bd76624b090faa6900739025d798a4e3130da80dbae15391b42b3d4672a4022", size = 69061, upload-time = "2025-08-14T08:59:15.228Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f9/180e953da537602d8530910f5a5f76c3d7215829d145d93f97fa43324dd7/cbor2-5.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:428d58b54a7b32ede869e79c294d686f826dcfdab9de7f92135dd3ce12e313b8", size = 284642, upload-time = "2025-08-14T08:59:16.511Z" }, - { url = "https://files.pythonhosted.org/packages/17/eb/7d79831a5081d25002e36a1b2685210ae8783582d1a99fae350b2b1b899c/cbor2-5.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a91b6912e2ff64f33464f67ec6528cf2e26c06a5f3cc3fb1954f94aa58d68670", size = 283690, upload-time = "2025-08-14T08:59:17.989Z" }, - { url = "https://files.pythonhosted.org/packages/38/43/1403610711ea6b9b957d86bd15fd0585a3917a3d9f8bafbb2cb1ad016361/cbor2-5.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9faeec4525fe3103a71f0fd3d6fe9a49ea6ff4ade8cb7cf1c395001b906a01e5", size = 276305, upload-time = "2025-08-14T08:59:19.43Z" }, - { url = "https://files.pythonhosted.org/packages/77/06/df4a5c7c16df3b604bd560234aff686da443bf70a124c5e3f80dff954e5a/cbor2-5.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:361315ccd8022c44bb501877fd9b236479c975f1a7aed69c8541bd609c0a8908", size = 277416, upload-time = "2025-08-14T08:59:20.798Z" }, - { url = "https://files.pythonhosted.org/packages/84/aa/62288bac4e501e25d04d50bb79ac46d4a6678ff9545941436a702c654eba/cbor2-5.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:293c4a5d6a9a69fcecf595a47430dc3b11f4a3355089b1fe300d0ac48c5776c5", size = 68378, upload-time = "2025-08-14T08:59:22.227Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d6/8358c144767731ffa03c16bb1222b59cb3be632833c70a2132cbe2ed8300/cbor2-5.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:52d6e1a9b2f4475540063d7b966b1b2e93ac497e08ab9a1514fd6330f8db5b4c", size = 63966, upload-time = "2025-08-14T08:59:23.369Z" }, - { url = "https://files.pythonhosted.org/packages/99/32/b653a2a3cfb283bdf0539dbd79d3bafa528aaa26fbe44796897d167e733d/cbor2-5.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f4f0464425ff809b1dd737db8c65a937516aba5eb3794cb1433f7eb8eb7a6535", size = 68993, upload-time = "2025-08-14T08:59:24.497Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/79d38f7f645a33e44b87f9333f74c04d01006a11f5291d2e8686815fe731/cbor2-5.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:866d993ebc9c4e4018ab001503dafc4145bb6ec91e1eddf12b8d7b6898021201", size = 69248, upload-time = "2025-08-14T08:59:25.63Z" }, - { url = "https://files.pythonhosted.org/packages/46/ca/59d65f12ef14c54c564f0e4363d9dd049a90d5b0e2a0dab0183062268a36/cbor2-5.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc7a11433ea1c45b6d47484bef99e822fd8a40b4cfbcdc1e00378a7e8704e317", size = 283739, upload-time = "2025-08-14T08:59:26.856Z" }, - { url = "https://files.pythonhosted.org/packages/19/51/5da8661b1aa7a4b7afe06724994b23eca6f7912d2cca705721dbd4aa764a/cbor2-5.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e33242570cb4542302dcb6cf429cc9abe315ff7ebb370de2828eed22a8b00fe8", size = 281246, upload-time = "2025-08-14T08:59:28.261Z" }, - { url = "https://files.pythonhosted.org/packages/d4/2f/565f5f215a9d4211c23e94c5b1761d697d248603ae11ecf83a9a70e99382/cbor2-5.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:855fe80517071028a5804a29b607864b8d90bbb2223331ab2d8cae94b979d61f", size = 275442, upload-time = "2025-08-14T08:59:29.794Z" }, - { url = "https://files.pythonhosted.org/packages/84/11/307a558f6ddc3bd0fc539ac65696acb0253554c88bab5da7d459706eb20e/cbor2-5.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:87170260845c2ea3d74288f667e0bc81c8a6bbc72ff60265d19c59b3e76be266", size = 275372, upload-time = "2025-08-14T08:59:31.589Z" }, - { url = "https://files.pythonhosted.org/packages/92/f0/960b7050a53b8d60f92e6e4c1ce670f9c50ab2ff48468e83b2bef0399b38/cbor2-5.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:a2b591904555e51843c95776df2d6b161226af045e655f464c101d8ad8708e99", size = 70188, upload-time = "2025-08-14T08:59:32.827Z" }, - { url = "https://files.pythonhosted.org/packages/a7/83/51805084b6208529f82e5a52261468a56b758728153ee2400c421fa845f4/cbor2-5.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:4460164ffd0ceaf8cc3f5597e73dd99fd781541c7bba0ea64ac93043bf08bb6a", size = 66162, upload-time = "2025-08-14T08:59:34.35Z" }, - { url = "https://files.pythonhosted.org/packages/41/cc/0ce73676d2a0c9e5a9330c301940c50eb325dacf5f6d9690fd43a8817fe9/cbor2-5.7.0-py3-none-any.whl", hash = "sha256:a871e7a6f7cba1ddb02503ea974f15f6524c95078fbfe0b860fd4193d7c8f27a", size = 23828, upload-time = "2025-08-14T08:59:46.129Z" }, +version = "5.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/b8/c0f6a7d46f816cb18b1fda61a2fe648abe16039f1ff93ea720a6e9fb3cee/cbor2-5.7.1.tar.gz", hash = "sha256:7a405a1d7c8230ee9acf240aad48ae947ef584e8af05f169f3c1bde8f01f8b71", size = 102467, upload-time = "2025-10-24T09:23:06.569Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/08/a9b3e777ace829d9d782f0a80877085af24708d73bd1c41c296aeba4ebac/cbor2-5.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a0fc6cc50e0aa04e54792e7824e65bf66c691ae2948d7c012153df2bab1ee314", size = 67914, upload-time = "2025-10-24T09:22:05.395Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b5/1c23af80b279d5ec336c57e41a53bf8158e2ec3610b415cbc74887145d5d/cbor2-5.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c2fe69c1473d18d102f1e20982edab5bfa543fa1cda9888bdecc49f8b2f3d720", size = 68445, upload-time = "2025-10-24T09:22:06.93Z" }, + { url = "https://files.pythonhosted.org/packages/f6/76/4d14dce9acd92333a249c676579e4879c492efda142c91c242044a70816d/cbor2-5.7.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34cbbe4fcf82080412a641984a0be43dfe66eac50a8f45596da63fde36189450", size = 254506, upload-time = "2025-10-24T09:22:08.264Z" }, + { url = "https://files.pythonhosted.org/packages/b0/70/d835e91d53bc9df4d77764262489b6de505cfa400799a6625e9368391ea7/cbor2-5.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fc3d3f00aed397a1e4634b8e1780f347aad191a2e1e7768a233baadd4f87561", size = 247760, upload-time = "2025-10-24T09:22:09.497Z" }, + { url = "https://files.pythonhosted.org/packages/29/c7/7fe1c82b5ddb00a407f016ca0de0560e47b3f6c15228478911b3b9ffb0e2/cbor2-5.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99e1666887a868e619096e9b5953734efd034f577e078f4efc5abd23dc1bcd32", size = 250188, upload-time = "2025-10-24T09:22:10.803Z" }, + { url = "https://files.pythonhosted.org/packages/49/fd/40887b1aee3270284d2e9ac6740566a554cb6fd7ca9f251d7e1ee86ba1c3/cbor2-5.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59b78c90a5e682e7d004586fb662be6e451ec06f32fc3a738bbfb9576c72ecc9", size = 244190, upload-time = "2025-10-24T09:22:12.294Z" }, + { url = "https://files.pythonhosted.org/packages/81/ba/9a91f4046c9a101fc68c23913c916d1fbcb6fae11d6a6f574f91c26ed31a/cbor2-5.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:6300e0322e52f831892054f1ccf25e67fa8040664963d358db090f29d8976ae4", size = 68150, upload-time = "2025-10-24T09:22:13.394Z" }, + { url = "https://files.pythonhosted.org/packages/12/1e/aad24a2fe0b54353e19aaad06f7d7eb2d835dc4f5bbf5882f98be20e8744/cbor2-5.7.1-cp310-cp310-win_arm64.whl", hash = "sha256:7badbde0d89eb7c8b9f7ef8e4f2395c02cfb24b514815656fef8e23276a7cd36", size = 64123, upload-time = "2025-10-24T09:22:14.669Z" }, + { url = "https://files.pythonhosted.org/packages/52/67/319baac9c51de0053f58fa74a9548f93f3629aa3adeebd7d2c99d1379370/cbor2-5.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b1efbe6e82721be44b9faf47d0fd97b0150213eb6a4ba554f4947442bc4e13f", size = 67894, upload-time = "2025-10-24T09:22:16.081Z" }, + { url = "https://files.pythonhosted.org/packages/2c/53/d23d0a234a4a098b019ac1cadd33631c973142fc947a68c4a38ca47aa5dc/cbor2-5.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb94bab27e00283bdd8f160e125e17dbabec4c9e6ffc8da91c36547ec1eb707f", size = 68444, upload-time = "2025-10-24T09:22:17.136Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a2/a6fa59e1c23b0bc77628d64153eb9fc69ac8dde5f8ed41a7d5316fcd0bcd/cbor2-5.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29f22266b5e08e0e4152e87ba185e04d3a84a4fd545b99ae3ebe42c658c66a53", size = 261600, upload-time = "2025-10-24T09:22:18.293Z" }, + { url = "https://files.pythonhosted.org/packages/3d/cb/e0fa066aa7a09b15b8f56bafef6b2be19d9db31310310b0a5601af5c0128/cbor2-5.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25d4c7554d6627da781c9bd1d0dd0709456eecb71f605829f98961bb98487dda", size = 254904, upload-time = "2025-10-24T09:22:19.645Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d5/b1fb4a3828c440e100a4b2658dd2e8f422faf08f4fcc8e2c92b240656b44/cbor2-5.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1e15c3a08008cf13ce1dfc64d17c960df5d66d935788d28ec7df54bf0ffb0ef", size = 257388, upload-time = "2025-10-24T09:22:20.805Z" }, + { url = "https://files.pythonhosted.org/packages/34/d5/252657bc5af964fc5f19c0e0e82031b4c32eba5d3ed4098e963e0e8c47a6/cbor2-5.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f6cdf7eb604ea0e7ef34e3f0b5447da0029ecd3ab7b2dc70e43fa5f7bcfca89", size = 251494, upload-time = "2025-10-24T09:22:21.986Z" }, + { url = "https://files.pythonhosted.org/packages/8a/3a/503ea4c2977411858ca287808d077fdb4bb1fafdb4b39177b8ce3d5619ac/cbor2-5.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:dd25cbef8e8e6dbf69f0de95311aecaca7217230cda83ae99fdc37cd20d99250", size = 68147, upload-time = "2025-10-24T09:22:23.136Z" }, + { url = "https://files.pythonhosted.org/packages/49/9e/fe4c9703fd444da193f892787110c5da2a85c16d26917fcb2584f5d00077/cbor2-5.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:40cc9c67242a7abac5a4e062bc4d1d2376979878c0565a4b2f08fd9ed9212945", size = 64126, upload-time = "2025-10-24T09:22:24.197Z" }, + { url = "https://files.pythonhosted.org/packages/56/54/48426472f0c051982c647331441aed09b271a0500356ae0b7054c813d174/cbor2-5.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bd5ca44891c06f6b85d440836c967187dc1d30b15f86f315d55c675d3a841078", size = 69031, upload-time = "2025-10-24T09:22:25.438Z" }, + { url = "https://files.pythonhosted.org/packages/d3/68/1dd58c7706e9752188358223db58c83f3c48e07f728aa84221ffd244652f/cbor2-5.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:537d73ef930ccc1a7b6a2e8d2cbf81407d270deb18e40cda5eb511bd70f71078", size = 68825, upload-time = "2025-10-24T09:22:26.497Z" }, + { url = "https://files.pythonhosted.org/packages/09/4e/380562fe9f9995a1875fb5ec26fd041e19d61f4630cb690a98c5195945fc/cbor2-5.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:edbf814dd7763b6eda27a5770199f6ccd55bd78be8f4367092460261bfbf19d0", size = 286222, upload-time = "2025-10-24T09:22:27.546Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/9eccdc1ea3c4d5c7cdb2e49b9de49534039616be5455ce69bd64c0b2efe2/cbor2-5.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fc81da8c0e09beb42923e455e477b36ff14a03b9ca18a8a2e9b462de9a953e8", size = 285688, upload-time = "2025-10-24T09:22:28.651Z" }, + { url = "https://files.pythonhosted.org/packages/59/8c/4696d82f5bd04b3d45d9a64ec037fa242630c134e3218d6c252b4f59b909/cbor2-5.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e4a7d660d428911a3aadb7105e94438d7671ab977356fdf647a91aab751033bd", size = 277063, upload-time = "2025-10-24T09:22:29.775Z" }, + { url = "https://files.pythonhosted.org/packages/95/50/6538e44ca970caaad2fa376b81701d073d84bf597aac07a59d0a253b1a7f/cbor2-5.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:228e0af9c0a9ddf6375b6ae010eaa1942a1901d403f134ac9ee6a76a322483f9", size = 278334, upload-time = "2025-10-24T09:22:30.904Z" }, + { url = "https://files.pythonhosted.org/packages/64/a9/156ccd2207fb26b5b61d23728b4dbdc595d1600125aa79683a4a8ddc9313/cbor2-5.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:2d08a6c0d9ed778448e185508d870f4160ba74f59bb17a966abd0d14d0ff4dd3", size = 68404, upload-time = "2025-10-24T09:22:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/4f/49/adc53615e9dd32c4421f6935dfa2235013532c6e6b28ee515bbdd92618be/cbor2-5.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:752506cfe72da0f4014b468b30191470ee8919a64a0772bd3b36a4fccf5fcefc", size = 64047, upload-time = "2025-10-24T09:22:33.147Z" }, + { url = "https://files.pythonhosted.org/packages/16/b1/51fb868fe38d893c570bb90b38d365ff0f00421402c1ae8f63b31b25d665/cbor2-5.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:59d5da59fffe89692d5bd1530eef4d26e4eb7aa794aaa1f4e192614786409009", size = 69068, upload-time = "2025-10-24T09:22:34.464Z" }, + { url = "https://files.pythonhosted.org/packages/b9/db/5abc62ec456f552f617aac3359a5d7114b23be9c4d886169592cd5f074b9/cbor2-5.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:533117918d518e01348f8cd0331271c207e7224b9a1ed492a0ff00847f28edc8", size = 68927, upload-time = "2025-10-24T09:22:35.458Z" }, + { url = "https://files.pythonhosted.org/packages/9a/c2/58d787395c99874d2a2395b3a22c9d48a3cfc5a7dcd5817bf74764998b75/cbor2-5.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8d6d9436ff3c3323ea5863ecf7ae1139590991685b44b9eb6b7bb1734a594af6", size = 285185, upload-time = "2025-10-24T09:22:36.867Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9c/b680b264a8f4b9aa59c95e166c816275a13138cbee92dd2917f58bca47b9/cbor2-5.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:661b871ca754a619fcd98c13a38b4696b2b57dab8b24235c00b0ba322c040d24", size = 284440, upload-time = "2025-10-24T09:22:38.08Z" }, + { url = "https://files.pythonhosted.org/packages/1f/59/68183c655d6226d0eee10027f52516882837802a8d5746317a88362ed686/cbor2-5.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8065aa90d715fd9bb28727b2d774ee16e695a0e1627ae76e54bf19f9d99d63f", size = 276876, upload-time = "2025-10-24T09:22:39.561Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a2/1964e0a569d2b81e8f4862753fee7701ae5773c22e45492a26f92f62e75a/cbor2-5.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cb1b7047d73590cfe8e373e2c804fa99be47e55b1b6186602d0f86f384cecec1", size = 278216, upload-time = "2025-10-24T09:22:41.132Z" }, + { url = "https://files.pythonhosted.org/packages/00/78/9b566d68cb88bb1ecebe354765625161c9d6060a16e55008006d6359f776/cbor2-5.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:31d511df7ebd6624fdb4cecdafb4ffb9a205f9ff8c8d98edd1bef0d27f944d74", size = 68451, upload-time = "2025-10-24T09:22:42.227Z" }, + { url = "https://files.pythonhosted.org/packages/db/85/7a6a922d147d027fd5d8fd5224b39e8eaf152a42e8cf16351458096d3d62/cbor2-5.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:f5d37f7b0f84394d2995bd8722cb01c86a885c4821a864a34b7b4d9950c5e26e", size = 64111, upload-time = "2025-10-24T09:22:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f0/f220222a57371e33434ba7bdc25de31d611cbc0ade2a868e03c3553305e7/cbor2-5.7.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e5826e4fa4c33661960073f99cf67c82783895524fb66f3ebdd635c19b5a7d68", size = 69002, upload-time = "2025-10-24T09:22:44.316Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3c/34b62ba5173541659f248f005d13373530f02fb997b78fde00bf01ede4f4/cbor2-5.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f19a00d6ac9a77cb611073250b06bf4494b41ba78a1716704f7008e0927d9366", size = 69177, upload-time = "2025-10-24T09:22:45.711Z" }, + { url = "https://files.pythonhosted.org/packages/77/fd/2400d820d9733df00a5c18aa74201e51d710fb91588687eb594f4a7688ea/cbor2-5.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d2113aea044cd172f199da3520bc4401af69eae96c5180ca7eb660941928cb89", size = 284259, upload-time = "2025-10-24T09:22:46.749Z" }, + { url = "https://files.pythonhosted.org/packages/42/65/280488ef196c1d71ba123cd406ea47727bb3a0e057767a733d9793fcc428/cbor2-5.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f17eacea2d28fecf28ac413c1d7927cde0a11957487d2630655d6b5c9c46a0b", size = 281958, upload-time = "2025-10-24T09:22:48.876Z" }, + { url = "https://files.pythonhosted.org/packages/42/82/bcdd3fdc73bd5f4194fdb08c808112010add9530bae1dcfdb1e2b2ceae19/cbor2-5.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d65deea39cae533a629561e7da672402c46731122b6129ed7c8eaa1efe04efce", size = 276025, upload-time = "2025-10-24T09:22:50.147Z" }, + { url = "https://files.pythonhosted.org/packages/ae/a8/a6065dd6a157b877d7d8f3fe96f410fb191a2db1e6588f4d20b5f9a507c2/cbor2-5.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:57d8cc29ec1fd20500748e0e767ff88c13afcee839081ba4478c41fcda6ee18b", size = 275978, upload-time = "2025-10-24T09:22:51.873Z" }, + { url = "https://files.pythonhosted.org/packages/62/f4/37934045174af9e4253a340b43f07197af54002070cb80fae82d878f1f14/cbor2-5.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:94fb939d0946f80c49ba45105ca3a3e13e598fc9abd63efc6661b02d4b4d2c50", size = 70269, upload-time = "2025-10-24T09:22:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/0b/fd/933416643e7f5540ae818691fb23fa4189010c6efa39a12c4f59d825da28/cbor2-5.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4fd7225ac820bbb9f03bd16bc1a7efb6c4d1c451f22c0a153ff4ec46495c59c5", size = 66182, upload-time = "2025-10-24T09:22:54.697Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7d/383bafeabb54c17fe5b6d5aca4e863e6b7df10bcc833b34aa169e9dfce1a/cbor2-5.7.1-py3-none-any.whl", hash = "sha256:68834e4eff2f56629ce6422b0634bc3f74c5a4269de5363f5265fe452c706ba7", size = 23829, upload-time = "2025-10-24T09:23:05.54Z" }, ] [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.11.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] [[package]] @@ -386,87 +380,112 @@ wheels = [ [[package]] name = "charset-normalizer" -version = "3.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, - { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, - { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, - { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, - { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, - { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, - { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, - { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, - { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, - { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, - { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, - { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, - { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, - { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, - { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, - { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, - { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, - { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", size = 209709, upload-time = "2025-10-14T04:40:11.385Z" }, + { url = "https://files.pythonhosted.org/packages/5c/af/1f9d7f7faafe2ddfb6f72a2e07a548a629c61ad510fe60f9630309908fef/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", size = 148814, upload-time = "2025-10-14T04:40:13.135Z" }, + { url = "https://files.pythonhosted.org/packages/79/3d/f2e3ac2bbc056ca0c204298ea4e3d9db9b4afe437812638759db2c976b5f/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", size = 144467, upload-time = "2025-10-14T04:40:14.728Z" }, + { url = "https://files.pythonhosted.org/packages/ec/85/1bf997003815e60d57de7bd972c57dc6950446a3e4ccac43bc3070721856/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", size = 162280, upload-time = "2025-10-14T04:40:16.14Z" }, + { url = "https://files.pythonhosted.org/packages/3e/8e/6aa1952f56b192f54921c436b87f2aaf7c7a7c3d0d1a765547d64fd83c13/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", size = 159454, upload-time = "2025-10-14T04:40:17.567Z" }, + { url = "https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", size = 153609, upload-time = "2025-10-14T04:40:19.08Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/6a13396948b8fd3c4b4fd5bc74d045f5637d78c9675585e8e9fbe5636554/charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", size = 151849, upload-time = "2025-10-14T04:40:20.607Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7a/59482e28b9981d105691e968c544cc0df3b7d6133152fb3dcdc8f135da7a/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", size = 151586, upload-time = "2025-10-14T04:40:21.719Z" }, + { url = "https://files.pythonhosted.org/packages/92/59/f64ef6a1c4bdd2baf892b04cd78792ed8684fbc48d4c2afe467d96b4df57/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", size = 145290, upload-time = "2025-10-14T04:40:23.069Z" }, + { url = "https://files.pythonhosted.org/packages/6b/63/3bf9f279ddfa641ffa1962b0db6a57a9c294361cc2f5fcac997049a00e9c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", size = 163663, upload-time = "2025-10-14T04:40:24.17Z" }, + { url = "https://files.pythonhosted.org/packages/ed/09/c9e38fc8fa9e0849b172b581fd9803bdf6e694041127933934184e19f8c3/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", size = 151964, upload-time = "2025-10-14T04:40:25.368Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d1/d28b747e512d0da79d8b6a1ac18b7ab2ecfd81b2944c4c710e166d8dd09c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", size = 161064, upload-time = "2025-10-14T04:40:26.806Z" }, + { url = "https://files.pythonhosted.org/packages/bb/9a/31d62b611d901c3b9e5500c36aab0ff5eb442043fb3a1c254200d3d397d9/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", size = 155015, upload-time = "2025-10-14T04:40:28.284Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/107e008fa2bff0c8b9319584174418e5e5285fef32f79d8ee6a430d0039c/charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", size = 99792, upload-time = "2025-10-14T04:40:29.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/66/e396e8a408843337d7315bab30dbf106c38966f1819f123257f5520f8a96/charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", size = 107198, upload-time = "2025-10-14T04:40:30.644Z" }, + { url = "https://files.pythonhosted.org/packages/b5/58/01b4f815bf0312704c267f2ccb6e5d42bcc7752340cd487bc9f8c3710597/charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", size = 100262, upload-time = "2025-10-14T04:40:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] name = "click" -version = "8.2.1" +version = "8.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] [[package]] name = "cloudpickle" -version = "3.1.1" +version = "3.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/39/069100b84d7418bc358d81669d5748efb14b9cceacd2f9c75f550424132f/cloudpickle-3.1.1.tar.gz", hash = "sha256:b216fa8ae4019d5482a8ac3c95d8f6346115d8835911fd4aefd1a445e4242c64", size = 22113, upload-time = "2025-01-14T17:02:05.085Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330, upload-time = "2025-11-03T09:25:26.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/e8/64c37fadfc2816a7701fa8a6ed8d87327c7d54eacfbfb6edab14a2f2be75/cloudpickle-3.1.1-py3-none-any.whl", hash = "sha256:c8c5a44295039331ee9dad40ba100a9c7297b6f988e50e87ccdf3765a668350e", size = 20992, upload-time = "2025-01-14T17:02:02.417Z" }, + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228, upload-time = "2025-11-03T09:25:25.534Z" }, ] [[package]] @@ -507,9 +526,7 @@ name = "contourpy" version = "1.3.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11'", ] dependencies = [ { name = "numpy", marker = "python_full_version < '3.11'" }, @@ -579,15 +596,9 @@ name = "contourpy" version = "1.3.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.13'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] dependencies = [ { name = "numpy", marker = "python_full_version >= '3.11'" }, @@ -696,86 +707,86 @@ wheels = [ [[package]] name = "filelock" -version = "3.19.1" +version = "3.20.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/23/ce7a1126827cedeb958fc043d61745754464eb56c5937c35bbf2b8e26f34/filelock-3.20.1.tar.gz", hash = "sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c", size = 19476, upload-time = "2025-12-15T23:54:28.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7f/a1a97644e39e7316d850784c642093c99df1290a460df4ede27659056834/filelock-3.20.1-py3-none-any.whl", hash = "sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a", size = 16666, upload-time = "2025-12-15T23:54:26.874Z" }, ] [[package]] name = "flatbuffers" -version = "25.2.10" +version = "25.9.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/30/eb5dce7994fc71a2f685d98ec33cc660c0a5887db5610137e60d8cbc4489/flatbuffers-25.2.10.tar.gz", hash = "sha256:97e451377a41262f8d9bd4295cc836133415cc03d8cb966410a4af92eb00d26e", size = 22170, upload-time = "2025-02-11T04:26:46.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/1f/3ee70b0a55137442038f2a33469cc5fddd7e0ad2abf83d7497c18a2b6923/flatbuffers-25.9.23.tar.gz", hash = "sha256:676f9fa62750bb50cf531b42a0a2a118ad8f7f797a511eda12881c016f093b12", size = 22067, upload-time = "2025-09-24T05:25:30.106Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/25/155f9f080d5e4bc0082edfda032ea2bc2b8fab3f4d25d46c1e9dd22a1a89/flatbuffers-25.2.10-py2.py3-none-any.whl", hash = "sha256:ebba5f4d5ea615af3f7fd70fc310636fbb2bbd1f566ac0a23d98dd412de50051", size = 30953, upload-time = "2025-02-11T04:26:44.484Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1b/00a78aa2e8fbd63f9af08c9c19e6deb3d5d66b4dda677a0f61654680ee89/flatbuffers-25.9.23-py2.py3-none-any.whl", hash = "sha256:255538574d6cb6d0a79a17ec8bc0d30985913b87513a01cce8bcdb6b4c44d0e2", size = 30869, upload-time = "2025-09-24T05:25:28.912Z" }, ] [[package]] name = "fonttools" -version = "4.59.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/7f/29c9c3fe4246f6ad96fee52b88d0dc3a863c7563b0afc959e36d78b965dc/fonttools-4.59.1.tar.gz", hash = "sha256:74995b402ad09822a4c8002438e54940d9f1ecda898d2bb057729d7da983e4cb", size = 3534394, upload-time = "2025-08-14T16:28:14.266Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/da/d66e5678802b2b662fd62908bf88b78d00bfb62de51660f270cf0dfce333/fonttools-4.59.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e90a89e52deb56b928e761bb5b5f65f13f669bfd96ed5962975debea09776a23", size = 2758395, upload-time = "2025-08-14T16:26:10.239Z" }, - { url = "https://files.pythonhosted.org/packages/96/74/d70a42bcc9ffa40a63e81417535b2849a702bd88f38bc2ed994ae86a2e74/fonttools-4.59.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d29ab70658d2ec19422b25e6ace00a0b0ae4181ee31e03335eaef53907d2d83", size = 2331647, upload-time = "2025-08-14T16:26:13.399Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f6/4a13657c9ca134ac62d9a68e4b3412b95b059537eab459cc1df653f45862/fonttools-4.59.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94f9721a564978a10d5c12927f99170d18e9a32e5a727c61eae56f956a4d118b", size = 4846293, upload-time = "2025-08-14T16:26:15.586Z" }, - { url = "https://files.pythonhosted.org/packages/69/e3/9f0c8c30eaea5b2d891bd95b000381b3b2dcaa89b5a064cce25157aba973/fonttools-4.59.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8c8758a7d97848fc8b514b3d9b4cb95243714b2f838dde5e1e3c007375de6214", size = 4776105, upload-time = "2025-08-14T16:26:17.624Z" }, - { url = "https://files.pythonhosted.org/packages/e2/73/1e6a06e2eecdc7b054b035507694b4f480e83b94dcb0d19f8a010d95350a/fonttools-4.59.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2aeb829ad9d41a2ef17cab8bb5d186049ba38a840f10352e654aa9062ec32dc1", size = 4825142, upload-time = "2025-08-14T16:26:19.936Z" }, - { url = "https://files.pythonhosted.org/packages/72/7d/a512521ec44c37bda27d08193e79e48a510a073554c30400ccc600494830/fonttools-4.59.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac216a2980a2d2b3b88c68a24f8a9bfb203e2490e991b3238502ad8f1e7bfed0", size = 4935220, upload-time = "2025-08-14T16:26:22.22Z" }, - { url = "https://files.pythonhosted.org/packages/62/f1/71f9a9c4e5df44d861975538a5c56b58f1662cd32ebbea5a02eb86028fc1/fonttools-4.59.1-cp310-cp310-win32.whl", hash = "sha256:d31dc137ed8ec71dbc446949eba9035926e6e967b90378805dcf667ff57cabb1", size = 2216883, upload-time = "2025-08-14T16:26:24.037Z" }, - { url = "https://files.pythonhosted.org/packages/f9/6d/92b2e3e0350bb3ef88024ae19513c12cee61896220e3df421c47a439af28/fonttools-4.59.1-cp310-cp310-win_amd64.whl", hash = "sha256:5265bc52ed447187d39891b5f21d7217722735d0de9fe81326566570d12851a9", size = 2261310, upload-time = "2025-08-14T16:26:26.184Z" }, - { url = "https://files.pythonhosted.org/packages/34/62/9667599561f623d4a523cc9eb4f66f3b94b6155464110fa9aebbf90bbec7/fonttools-4.59.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4909cce2e35706f3d18c54d3dcce0414ba5e0fb436a454dffec459c61653b513", size = 2778815, upload-time = "2025-08-14T16:26:28.484Z" }, - { url = "https://files.pythonhosted.org/packages/8f/78/cc25bcb2ce86033a9df243418d175e58f1956a35047c685ef553acae67d6/fonttools-4.59.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:efbec204fa9f877641747f2d9612b2b656071390d7a7ef07a9dbf0ecf9c7195c", size = 2341631, upload-time = "2025-08-14T16:26:30.396Z" }, - { url = "https://files.pythonhosted.org/packages/a4/cc/fcbb606dd6871f457ac32f281c20bcd6cc77d9fce77b5a4e2b2afab1f500/fonttools-4.59.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39dfd42cc2dc647b2c5469bc7a5b234d9a49e72565b96dd14ae6f11c2c59ef15", size = 5022222, upload-time = "2025-08-14T16:26:32.447Z" }, - { url = "https://files.pythonhosted.org/packages/61/96/c0b1cf2b74d08eb616a80dbf5564351fe4686147291a25f7dce8ace51eb3/fonttools-4.59.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b11bc177a0d428b37890825d7d025040d591aa833f85f8d8878ed183354f47df", size = 4966512, upload-time = "2025-08-14T16:26:34.621Z" }, - { url = "https://files.pythonhosted.org/packages/a4/26/51ce2e3e0835ffc2562b1b11d1fb9dafd0aca89c9041b64a9e903790a761/fonttools-4.59.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b9b4c35b3be45e5bc774d3fc9608bbf4f9a8d371103b858c80edbeed31dd5aa", size = 5001645, upload-time = "2025-08-14T16:26:36.876Z" }, - { url = "https://files.pythonhosted.org/packages/36/11/ef0b23f4266349b6d5ccbd1a07b7adc998d5bce925792aa5d1ec33f593e3/fonttools-4.59.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:01158376b8a418a0bae9625c476cebfcfcb5e6761e9d243b219cd58341e7afbb", size = 5113777, upload-time = "2025-08-14T16:26:39.002Z" }, - { url = "https://files.pythonhosted.org/packages/d0/da/b398fe61ef433da0a0472cdb5d4399124f7581ffe1a31b6242c91477d802/fonttools-4.59.1-cp311-cp311-win32.whl", hash = "sha256:cf7c5089d37787387123f1cb8f1793a47c5e1e3d1e4e7bfbc1cc96e0f925eabe", size = 2215076, upload-time = "2025-08-14T16:26:41.196Z" }, - { url = "https://files.pythonhosted.org/packages/94/bd/e2624d06ab94e41c7c77727b2941f1baed7edb647e63503953e6888020c9/fonttools-4.59.1-cp311-cp311-win_amd64.whl", hash = "sha256:c866eef7a0ba320486ade6c32bfc12813d1a5db8567e6904fb56d3d40acc5116", size = 2262779, upload-time = "2025-08-14T16:26:43.483Z" }, - { url = "https://files.pythonhosted.org/packages/ac/fe/6e069cc4cb8881d164a9bd956e9df555bc62d3eb36f6282e43440200009c/fonttools-4.59.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:43ab814bbba5f02a93a152ee61a04182bb5809bd2bc3609f7822e12c53ae2c91", size = 2769172, upload-time = "2025-08-14T16:26:45.729Z" }, - { url = "https://files.pythonhosted.org/packages/b9/98/ec4e03f748fefa0dd72d9d95235aff6fef16601267f4a2340f0e16b9330f/fonttools-4.59.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4f04c3ffbfa0baafcbc550657cf83657034eb63304d27b05cff1653b448ccff6", size = 2337281, upload-time = "2025-08-14T16:26:47.921Z" }, - { url = "https://files.pythonhosted.org/packages/8b/b1/890360a7e3d04a30ba50b267aca2783f4c1364363797e892e78a4f036076/fonttools-4.59.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d601b153e51a5a6221f0d4ec077b6bfc6ac35bfe6c19aeaa233d8990b2b71726", size = 4909215, upload-time = "2025-08-14T16:26:49.682Z" }, - { url = "https://files.pythonhosted.org/packages/8a/ec/2490599550d6c9c97a44c1e36ef4de52d6acf742359eaa385735e30c05c4/fonttools-4.59.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c735e385e30278c54f43a0d056736942023c9043f84ee1021eff9fd616d17693", size = 4951958, upload-time = "2025-08-14T16:26:51.616Z" }, - { url = "https://files.pythonhosted.org/packages/d1/40/bd053f6f7634234a9b9805ff8ae4f32df4f2168bee23cafd1271ba9915a9/fonttools-4.59.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1017413cdc8555dce7ee23720da490282ab7ec1cf022af90a241f33f9a49afc4", size = 4894738, upload-time = "2025-08-14T16:26:53.836Z" }, - { url = "https://files.pythonhosted.org/packages/ac/a1/3cd12a010d288325a7cfcf298a84825f0f9c29b01dee1baba64edfe89257/fonttools-4.59.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5c6d8d773470a5107052874341ed3c487c16ecd179976d81afed89dea5cd7406", size = 5045983, upload-time = "2025-08-14T16:26:56.153Z" }, - { url = "https://files.pythonhosted.org/packages/a2/af/8a2c3f6619cc43cf87951405337cc8460d08a4e717bb05eaa94b335d11dc/fonttools-4.59.1-cp312-cp312-win32.whl", hash = "sha256:2a2d0d33307f6ad3a2086a95dd607c202ea8852fa9fb52af9b48811154d1428a", size = 2203407, upload-time = "2025-08-14T16:26:58.165Z" }, - { url = "https://files.pythonhosted.org/packages/8e/f2/a19b874ddbd3ebcf11d7e25188ef9ac3f68b9219c62263acb34aca8cde05/fonttools-4.59.1-cp312-cp312-win_amd64.whl", hash = "sha256:0b9e4fa7eaf046ed6ac470f6033d52c052481ff7a6e0a92373d14f556f298dc0", size = 2251561, upload-time = "2025-08-14T16:27:00.646Z" }, - { url = "https://files.pythonhosted.org/packages/19/5e/94a4d7f36c36e82f6a81e0064d148542e0ad3e6cf51fc5461ca128f3658d/fonttools-4.59.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:89d9957b54246c6251345297dddf77a84d2c19df96af30d2de24093bbdf0528b", size = 2760192, upload-time = "2025-08-14T16:27:03.024Z" }, - { url = "https://files.pythonhosted.org/packages/ee/a5/f50712fc33ef9d06953c660cefaf8c8fe4b8bc74fa21f44ee5e4f9739439/fonttools-4.59.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8156b11c0d5405810d216f53907bd0f8b982aa5f1e7e3127ab3be1a4062154ff", size = 2332694, upload-time = "2025-08-14T16:27:04.883Z" }, - { url = "https://files.pythonhosted.org/packages/e9/a2/5a9fc21c354bf8613215ce233ab0d933bd17d5ff4c29693636551adbc7b3/fonttools-4.59.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8387876a8011caec52d327d5e5bca705d9399ec4b17afb8b431ec50d47c17d23", size = 4889254, upload-time = "2025-08-14T16:27:07.02Z" }, - { url = "https://files.pythonhosted.org/packages/2d/e5/54a6dc811eba018d022ca2e8bd6f2969291f9586ccf9a22a05fc55f91250/fonttools-4.59.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb13823a74b3a9204a8ed76d3d6d5ec12e64cc5bc44914eb9ff1cdac04facd43", size = 4949109, upload-time = "2025-08-14T16:27:09.3Z" }, - { url = "https://files.pythonhosted.org/packages/db/15/b05c72a248a95bea0fd05fbd95acdf0742945942143fcf961343b7a3663a/fonttools-4.59.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e1ca10da138c300f768bb68e40e5b20b6ecfbd95f91aac4cc15010b6b9d65455", size = 4888428, upload-time = "2025-08-14T16:27:11.514Z" }, - { url = "https://files.pythonhosted.org/packages/63/71/c7d6840f858d695adc0c4371ec45e3fb1c8e060b276ba944e2800495aca4/fonttools-4.59.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2beb5bfc4887a3130f8625349605a3a45fe345655ce6031d1bac11017454b943", size = 5032668, upload-time = "2025-08-14T16:27:13.872Z" }, - { url = "https://files.pythonhosted.org/packages/90/54/57be4aca6f1312e2bc4d811200dd822325794e05bdb26eeff0976edca651/fonttools-4.59.1-cp313-cp313-win32.whl", hash = "sha256:419f16d750d78e6d704bfe97b48bba2f73b15c9418f817d0cb8a9ca87a5b94bf", size = 2201832, upload-time = "2025-08-14T16:27:16.126Z" }, - { url = "https://files.pythonhosted.org/packages/fc/1f/1899a6175a5f900ed8730a0d64f53ca1b596ed7609bfda033cf659114258/fonttools-4.59.1-cp313-cp313-win_amd64.whl", hash = "sha256:c536f8a852e8d3fa71dde1ec03892aee50be59f7154b533f0bf3c1174cfd5126", size = 2250673, upload-time = "2025-08-14T16:27:18.033Z" }, - { url = "https://files.pythonhosted.org/packages/15/07/f6ba82c22f118d9985c37fea65d8d715ca71300d78b6c6e90874dc59f11d/fonttools-4.59.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:d5c3bfdc9663f3d4b565f9cb3b8c1efb3e178186435b45105bde7328cfddd7fe", size = 2758606, upload-time = "2025-08-14T16:27:20.064Z" }, - { url = "https://files.pythonhosted.org/packages/3a/81/84aa3d0ce27b0112c28b67b637ff7a47cf401cf5fbfee6476e4bc9777580/fonttools-4.59.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ea03f1da0d722fe3c2278a05957e6550175571a4894fbf9d178ceef4a3783d2b", size = 2330187, upload-time = "2025-08-14T16:27:22.42Z" }, - { url = "https://files.pythonhosted.org/packages/17/41/b3ba43f78afb321e2e50232c87304c8d0f5ab39b64389b8286cc39cdb824/fonttools-4.59.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:57a3708ca6bfccb790f585fa6d8f29432ec329618a09ff94c16bcb3c55994643", size = 4832020, upload-time = "2025-08-14T16:27:24.214Z" }, - { url = "https://files.pythonhosted.org/packages/67/b1/3af871c7fb325a68938e7ce544ca48bfd2c6bb7b357f3c8252933b29100a/fonttools-4.59.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:729367c91eb1ee84e61a733acc485065a00590618ca31c438e7dd4d600c01486", size = 4930687, upload-time = "2025-08-14T16:27:26.484Z" }, - { url = "https://files.pythonhosted.org/packages/c5/4f/299fc44646b30d9ef03ffaa78b109c7bd32121f0d8f10009ee73ac4514bc/fonttools-4.59.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f8ef66ac6db450193ed150e10b3b45dde7aded10c5d279968bc63368027f62b", size = 4875794, upload-time = "2025-08-14T16:27:28.887Z" }, - { url = "https://files.pythonhosted.org/packages/90/cf/a0a3d763ab58f5f81ceff104ddb662fd9da94248694862b9c6cbd509fdd5/fonttools-4.59.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:075f745d539a998cd92cb84c339a82e53e49114ec62aaea8307c80d3ad3aef3a", size = 4985780, upload-time = "2025-08-14T16:27:30.858Z" }, - { url = "https://files.pythonhosted.org/packages/72/c5/ba76511aaae143d89c29cd32ce30bafb61c477e8759a1590b8483f8065f8/fonttools-4.59.1-cp314-cp314-win32.whl", hash = "sha256:c2b0597522d4c5bb18aa5cf258746a2d4a90f25878cbe865e4d35526abd1b9fc", size = 2205610, upload-time = "2025-08-14T16:27:32.578Z" }, - { url = "https://files.pythonhosted.org/packages/a9/65/b250e69d6caf35bc65cddbf608be0662d741c248f2e7503ab01081fc267e/fonttools-4.59.1-cp314-cp314-win_amd64.whl", hash = "sha256:e9ad4ce044e3236f0814c906ccce8647046cc557539661e35211faadf76f283b", size = 2255376, upload-time = "2025-08-14T16:27:34.653Z" }, - { url = "https://files.pythonhosted.org/packages/11/f3/0bc63a23ac0f8175e23d82f85d6ee693fbd849de7ad739f0a3622182ad29/fonttools-4.59.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:652159e8214eb4856e8387ebcd6b6bd336ee258cbeb639c8be52005b122b9609", size = 2826546, upload-time = "2025-08-14T16:27:36.783Z" }, - { url = "https://files.pythonhosted.org/packages/e9/46/a3968205590e068fdf60e926be329a207782576cb584d3b7dcd2d2844957/fonttools-4.59.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:43d177cd0e847ea026fedd9f099dc917da136ed8792d142298a252836390c478", size = 2359771, upload-time = "2025-08-14T16:27:39.678Z" }, - { url = "https://files.pythonhosted.org/packages/b8/ff/d14b4c283879e8cb57862d9624a34fe6522b6fcdd46ccbfc58900958794a/fonttools-4.59.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e54437651e1440ee53a95e6ceb6ee440b67a3d348c76f45f4f48de1a5ecab019", size = 4831575, upload-time = "2025-08-14T16:27:41.885Z" }, - { url = "https://files.pythonhosted.org/packages/9c/04/a277d9a584a49d98ca12d3b2c6663bdf333ae97aaa83bd0cdabf7c5a6c84/fonttools-4.59.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6065fdec8ff44c32a483fd44abe5bcdb40dd5e2571a5034b555348f2b3a52cea", size = 5069962, upload-time = "2025-08-14T16:27:44.284Z" }, - { url = "https://files.pythonhosted.org/packages/16/6f/3d2ae69d96c4cdee6dfe7598ca5519a1514487700ca3d7c49c5a1ad65308/fonttools-4.59.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42052b56d176f8b315fbc09259439c013c0cb2109df72447148aeda677599612", size = 4942926, upload-time = "2025-08-14T16:27:46.523Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d3/c17379e0048d03ce26b38e4ab0e9a98280395b00529e093fe2d663ac0658/fonttools-4.59.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bcd52eaa5c4c593ae9f447c1d13e7e4a00ca21d755645efa660b6999425b3c88", size = 4958678, upload-time = "2025-08-14T16:27:48.555Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3f/c5543a1540abdfb4d375e3ebeb84de365ab9b153ec14cb7db05f537dd1e7/fonttools-4.59.1-cp314-cp314t-win32.whl", hash = "sha256:02e4fdf27c550dded10fe038a5981c29f81cb9bc649ff2eaa48e80dab8998f97", size = 2266706, upload-time = "2025-08-14T16:27:50.556Z" }, - { url = "https://files.pythonhosted.org/packages/3e/99/85bff6e674226bc8402f983e365f07e76d990e7220ba72bcc738fef52391/fonttools-4.59.1-cp314-cp314t-win_amd64.whl", hash = "sha256:412a5fd6345872a7c249dac5bcce380393f40c1c316ac07f447bc17d51900922", size = 2329994, upload-time = "2025-08-14T16:27:52.36Z" }, - { url = "https://files.pythonhosted.org/packages/0f/64/9d606e66d498917cd7a2ff24f558010d42d6fd4576d9dd57f0bd98333f5a/fonttools-4.59.1-py3-none-any.whl", hash = "sha256:647db657073672a8330608970a984d51573557f328030566521bc03415535042", size = 1130094, upload-time = "2025-08-14T16:28:12.048Z" }, +version = "4.61.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/ca/cf17b88a8df95691275a3d77dc0a5ad9907f328ae53acbe6795da1b2f5ed/fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69", size = 3565756, upload-time = "2025-12-12T17:31:24.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/94/8a28707adb00bed1bf22dac16ccafe60faf2ade353dcb32c3617ee917307/fonttools-4.61.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c7db70d57e5e1089a274cbb2b1fd635c9a24de809a231b154965d415d6c6d24", size = 2854799, upload-time = "2025-12-12T17:29:27.5Z" }, + { url = "https://files.pythonhosted.org/packages/94/93/c2e682faaa5ee92034818d8f8a8145ae73eb83619600495dcf8503fa7771/fonttools-4.61.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5fe9fd43882620017add5eabb781ebfbc6998ee49b35bd7f8f79af1f9f99a958", size = 2403032, upload-time = "2025-12-12T17:29:30.115Z" }, + { url = "https://files.pythonhosted.org/packages/f1/62/1748f7e7e1ee41aa52279fd2e3a6d0733dc42a673b16932bad8e5d0c8b28/fonttools-4.61.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8db08051fc9e7d8bc622f2112511b8107d8f27cd89e2f64ec45e9825e8288da", size = 4897863, upload-time = "2025-12-12T17:29:32.535Z" }, + { url = "https://files.pythonhosted.org/packages/69/69/4ca02ee367d2c98edcaeb83fc278d20972502ee071214ad9d8ca85e06080/fonttools-4.61.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a76d4cb80f41ba94a6691264be76435e5f72f2cb3cab0b092a6212855f71c2f6", size = 4859076, upload-time = "2025-12-12T17:29:34.907Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f5/660f9e3cefa078861a7f099107c6d203b568a6227eef163dd173bfc56bdc/fonttools-4.61.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a13fc8aeb24bad755eea8f7f9d409438eb94e82cf86b08fe77a03fbc8f6a96b1", size = 4875623, upload-time = "2025-12-12T17:29:37.33Z" }, + { url = "https://files.pythonhosted.org/packages/63/d1/9d7c5091d2276ed47795c131c1bf9316c3c1ab2789c22e2f59e0572ccd38/fonttools-4.61.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b846a1fcf8beadeb9ea4f44ec5bdde393e2f1569e17d700bfc49cd69bde75881", size = 4993327, upload-time = "2025-12-12T17:29:39.781Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2d/28def73837885ae32260d07660a052b99f0aa00454867d33745dfe49dbf0/fonttools-4.61.1-cp310-cp310-win32.whl", hash = "sha256:78a7d3ab09dc47ac1a363a493e6112d8cabed7ba7caad5f54dbe2f08676d1b47", size = 1502180, upload-time = "2025-12-12T17:29:42.217Z" }, + { url = "https://files.pythonhosted.org/packages/63/fa/bfdc98abb4dd2bd491033e85e3ba69a2313c850e759a6daa014bc9433b0f/fonttools-4.61.1-cp310-cp310-win_amd64.whl", hash = "sha256:eff1ac3cc66c2ac7cda1e64b4e2f3ffef474b7335f92fc3833fc632d595fcee6", size = 1550654, upload-time = "2025-12-12T17:29:44.564Z" }, + { url = "https://files.pythonhosted.org/packages/69/12/bf9f4eaa2fad039356cc627587e30ed008c03f1cebd3034376b5ee8d1d44/fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09", size = 2852213, upload-time = "2025-12-12T17:29:46.675Z" }, + { url = "https://files.pythonhosted.org/packages/ac/49/4138d1acb6261499bedde1c07f8c2605d1d8f9d77a151e5507fd3ef084b6/fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37", size = 2401689, upload-time = "2025-12-12T17:29:48.769Z" }, + { url = "https://files.pythonhosted.org/packages/e5/fe/e6ce0fe20a40e03aef906af60aa87668696f9e4802fa283627d0b5ed777f/fonttools-4.61.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb", size = 5058809, upload-time = "2025-12-12T17:29:51.701Z" }, + { url = "https://files.pythonhosted.org/packages/79/61/1ca198af22f7dd22c17ab86e9024ed3c06299cfdb08170640e9996d501a0/fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9", size = 5036039, upload-time = "2025-12-12T17:29:53.659Z" }, + { url = "https://files.pythonhosted.org/packages/99/cc/fa1801e408586b5fce4da9f5455af8d770f4fc57391cd5da7256bb364d38/fonttools-4.61.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87", size = 5034714, upload-time = "2025-12-12T17:29:55.592Z" }, + { url = "https://files.pythonhosted.org/packages/bf/aa/b7aeafe65adb1b0a925f8f25725e09f078c635bc22754f3fecb7456955b0/fonttools-4.61.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56", size = 5158648, upload-time = "2025-12-12T17:29:57.861Z" }, + { url = "https://files.pythonhosted.org/packages/99/f9/08ea7a38663328881384c6e7777bbefc46fd7d282adfd87a7d2b84ec9d50/fonttools-4.61.1-cp311-cp311-win32.whl", hash = "sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a", size = 2280681, upload-time = "2025-12-12T17:29:59.943Z" }, + { url = "https://files.pythonhosted.org/packages/07/ad/37dd1ae5fa6e01612a1fbb954f0927681f282925a86e86198ccd7b15d515/fonttools-4.61.1-cp311-cp311-win_amd64.whl", hash = "sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7", size = 2331951, upload-time = "2025-12-12T17:30:02.254Z" }, + { url = "https://files.pythonhosted.org/packages/6f/16/7decaa24a1bd3a70c607b2e29f0adc6159f36a7e40eaba59846414765fd4/fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e", size = 2851593, upload-time = "2025-12-12T17:30:04.225Z" }, + { url = "https://files.pythonhosted.org/packages/94/98/3c4cb97c64713a8cf499b3245c3bf9a2b8fd16a3e375feff2aed78f96259/fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2", size = 2400231, upload-time = "2025-12-12T17:30:06.47Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/82dbef0f6342eb01f54bca073ac1498433d6ce71e50c3c3282b655733b31/fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796", size = 4954103, upload-time = "2025-12-12T17:30:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/6c/44/f3aeac0fa98e7ad527f479e161aca6c3a1e47bb6996b053d45226fe37bf2/fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d", size = 5004295, upload-time = "2025-12-12T17:30:10.56Z" }, + { url = "https://files.pythonhosted.org/packages/14/e8/7424ced75473983b964d09f6747fa09f054a6d656f60e9ac9324cf40c743/fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8", size = 4944109, upload-time = "2025-12-12T17:30:12.874Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8b/6391b257fa3d0b553d73e778f953a2f0154292a7a7a085e2374b111e5410/fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0", size = 5093598, upload-time = "2025-12-12T17:30:15.79Z" }, + { url = "https://files.pythonhosted.org/packages/d9/71/fd2ea96cdc512d92da5678a1c98c267ddd4d8c5130b76d0f7a80f9a9fde8/fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261", size = 2269060, upload-time = "2025-12-12T17:30:18.058Z" }, + { url = "https://files.pythonhosted.org/packages/80/3b/a3e81b71aed5a688e89dfe0e2694b26b78c7d7f39a5ffd8a7d75f54a12a8/fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9", size = 2319078, upload-time = "2025-12-12T17:30:22.862Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c", size = 2846454, upload-time = "2025-12-12T17:30:24.938Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e", size = 2398191, upload-time = "2025-12-12T17:30:27.343Z" }, + { url = "https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5", size = 4928410, upload-time = "2025-12-12T17:30:29.771Z" }, + { url = "https://files.pythonhosted.org/packages/b0/8d/6fb3494dfe61a46258cd93d979cf4725ded4eb46c2a4ca35e4490d84daea/fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd", size = 4984460, upload-time = "2025-12-12T17:30:32.073Z" }, + { url = "https://files.pythonhosted.org/packages/f7/f1/a47f1d30b3dc00d75e7af762652d4cbc3dff5c2697a0dbd5203c81afd9c3/fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3", size = 4925800, upload-time = "2025-12-12T17:30:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/a7/01/e6ae64a0981076e8a66906fab01539799546181e32a37a0257b77e4aa88b/fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d", size = 5067859, upload-time = "2025-12-12T17:30:36.593Z" }, + { url = "https://files.pythonhosted.org/packages/73/aa/28e40b8d6809a9b5075350a86779163f074d2b617c15d22343fce81918db/fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c", size = 2267821, upload-time = "2025-12-12T17:30:38.478Z" }, + { url = "https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b", size = 2318169, upload-time = "2025-12-12T17:30:40.951Z" }, + { url = "https://files.pythonhosted.org/packages/32/8f/4e7bf82c0cbb738d3c2206c920ca34ca74ef9dabde779030145d28665104/fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd", size = 2846094, upload-time = "2025-12-12T17:30:43.511Z" }, + { url = "https://files.pythonhosted.org/packages/71/09/d44e45d0a4f3a651f23a1e9d42de43bc643cce2971b19e784cc67d823676/fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e", size = 2396589, upload-time = "2025-12-12T17:30:45.681Z" }, + { url = "https://files.pythonhosted.org/packages/89/18/58c64cafcf8eb677a99ef593121f719e6dcbdb7d1c594ae5a10d4997ca8a/fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c", size = 4877892, upload-time = "2025-12-12T17:30:47.709Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ec/9e6b38c7ba1e09eb51db849d5450f4c05b7e78481f662c3b79dbde6f3d04/fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75", size = 4972884, upload-time = "2025-12-12T17:30:49.656Z" }, + { url = "https://files.pythonhosted.org/packages/5e/87/b5339da8e0256734ba0dbbf5b6cdebb1dd79b01dc8c270989b7bcd465541/fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063", size = 4924405, upload-time = "2025-12-12T17:30:51.735Z" }, + { url = "https://files.pythonhosted.org/packages/0b/47/e3409f1e1e69c073a3a6fd8cb886eb18c0bae0ee13db2c8d5e7f8495e8b7/fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2", size = 5035553, upload-time = "2025-12-12T17:30:54.823Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/1f6600161b1073a984294c6c031e1a56ebf95b6164249eecf30012bb2e38/fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c", size = 2271915, upload-time = "2025-12-12T17:30:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/52/7b/91e7b01e37cc8eb0e1f770d08305b3655e4f002fc160fb82b3390eabacf5/fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c", size = 2323487, upload-time = "2025-12-12T17:30:59.804Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/908ad78e46c61c3e3ed70c3b58ff82ab48437faf84ec84f109592cabbd9f/fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa", size = 2929571, upload-time = "2025-12-12T17:31:02.574Z" }, + { url = "https://files.pythonhosted.org/packages/bd/41/975804132c6dea64cdbfbaa59f3518a21c137a10cccf962805b301ac6ab2/fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91", size = 2435317, upload-time = "2025-12-12T17:31:04.974Z" }, + { url = "https://files.pythonhosted.org/packages/b0/5a/aef2a0a8daf1ebaae4cfd83f84186d4a72ee08fd6a8451289fcd03ffa8a4/fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19", size = 4882124, upload-time = "2025-12-12T17:31:07.456Z" }, + { url = "https://files.pythonhosted.org/packages/80/33/d6db3485b645b81cea538c9d1c9219d5805f0877fda18777add4671c5240/fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba", size = 5100391, upload-time = "2025-12-12T17:31:09.732Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d6/675ba631454043c75fcf76f0ca5463eac8eb0666ea1d7badae5fea001155/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7", size = 4978800, upload-time = "2025-12-12T17:31:11.681Z" }, + { url = "https://files.pythonhosted.org/packages/7f/33/d3ec753d547a8d2bdaedd390d4a814e8d5b45a093d558f025c6b990b554c/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118", size = 5006426, upload-time = "2025-12-12T17:31:13.764Z" }, + { url = "https://files.pythonhosted.org/packages/b4/40/cc11f378b561a67bea850ab50063366a0d1dd3f6d0a30ce0f874b0ad5664/fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5", size = 2335377, upload-time = "2025-12-12T17:31:16.49Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ff/c9a2b66b39f8628531ea58b320d66d951267c98c6a38684daa8f50fb02f8/fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b", size = 2400613, upload-time = "2025-12-12T17:31:18.769Z" }, + { url = "https://files.pythonhosted.org/packages/c7/4e/ce75a57ff3aebf6fc1f4e9d508b8e5810618a33d900ad6c19eb30b290b97/fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371", size = 1148996, upload-time = "2025-12-12T17:31:21.03Z" }, ] [[package]] name = "fsspec" -version = "2025.7.0" +version = "2025.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/02/0835e6ab9cfc03916fe3f78c0956cfcdb6ff2669ffa6651065d5ebf7fc98/fsspec-2025.7.0.tar.gz", hash = "sha256:786120687ffa54b8283d942929540d8bc5ccfa820deb555a2b5d0ed2b737bf58", size = 304432, upload-time = "2025-07-15T16:05:21.19Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/e0/014d5d9d7a4564cf1c40b5039bc882db69fd881111e03ab3657ac0b218e2/fsspec-2025.7.0-py3-none-any.whl", hash = "sha256:8b012e39f63c7d5f10474de957f3ab793b47b45ae7d39f2fb735f8bbe25c0e21", size = 199597, upload-time = "2025-07-15T16:05:19.529Z" }, + { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, ] [[package]] @@ -828,7 +839,7 @@ wheels = [ [[package]] name = "gymnasium" -version = "1.2.0" +version = "1.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cloudpickle" }, @@ -836,9 +847,9 @@ dependencies = [ { name = "numpy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/17/c2a0e15c2cd5a8e788389b280996db927b923410de676ec5c7b2695e9261/gymnasium-1.2.0.tar.gz", hash = "sha256:344e87561012558f603880baf264ebc97f8a5c997a957b0c9f910281145534b0", size = 821142, upload-time = "2025-06-27T08:21:20.262Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/1c/d70b2ddd067992fa0332deae08293ef2dc489917ac5342e0e4b8850641f6/gymnasium-1.2.2.tar.gz", hash = "sha256:46d927328f8518bb5a689dbe270d228c1da2b08bcb71ae0152c10aa66f48d530", size = 829250, upload-time = "2025-11-04T15:21:06.048Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e2/a111dbb8625af467ea4760a1373d6ef27aac3137931219902406ccc05423/gymnasium-1.2.0-py3-none-any.whl", hash = "sha256:fc4a1e4121a9464c29b4d7dc6ade3fbeaa36dea448682f5f71a6d2c17489ea76", size = 944301, upload-time = "2025-06-27T08:21:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/c7/53/39cd8c2f85e213fce1f32367c4bdbd3402d3bcde7d0826a1172a0f2c5cc0/gymnasium-1.2.2-py3-none-any.whl", hash = "sha256:f04ec362b1fdf73a8b327db5ef89384a3f2ba411e05d3521513414fbbb2199c8", size = 952118, upload-time = "2025-11-04T15:21:03.484Z" }, ] [[package]] @@ -855,11 +866,11 @@ wheels = [ [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] @@ -997,16 +1008,16 @@ wheels = [ [[package]] name = "luma-core" -version = "2.5.1" +version = "2.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cbor2" }, { name = "pillow" }, { name = "smbus2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/1a/e706039601ac5a3e3a13a5baf8d9fc3764a62e425a674c296f7ddfc546a0/luma_core-2.5.1.tar.gz", hash = "sha256:9b88fbe868989ec4477e210fe2993e774a7425d7de8378814109f98be32ca653", size = 102996, upload-time = "2025-07-20T16:18:38.637Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/55/efc1f2a4c18f34a185d6a15152467feefcb461c9d4022f41ac57f5e38395/luma_core-2.5.2.tar.gz", hash = "sha256:2e46f8756dce49d3b5393dab7b521c3bc6dad6f5e6a6208b55bca0b711adfb31", size = 103186, upload-time = "2025-11-07T17:18:11.002Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/9e/1df4b80a434f7918b2e691ff289e1054194fcb3f4498b754efa7fb6f3d75/luma_core-2.5.1-py2.py3-none-any.whl", hash = "sha256:4af3ae09e04dd3f2a29a6ea005bf3d06cf8b809a9337b6550c747613e84d19b3", size = 71038, upload-time = "2025-07-20T16:18:37.091Z" }, + { url = "https://files.pythonhosted.org/packages/44/2c/0d9d2e96fd953cbc824cf1323650a9e03c5675b2542a4881b656d98e19ed/luma_core-2.5.2-py3-none-any.whl", hash = "sha256:56dbabd7a279e57dff840e4990eb255de9fd2932fe8175921040f9f387847060", size = 71117, upload-time = "2025-11-07T17:18:09.264Z" }, ] [[package]] @@ -1023,74 +1034,101 @@ wheels = [ [[package]] name = "markdown" -version = "3.8.2" +version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/c2/4ab49206c17f75cb08d6311171f2d65798988db4360c4d1485bd0eedd67c/markdown-3.8.2.tar.gz", hash = "sha256:247b9a70dd12e27f67431ce62523e675b866d254f900c4fe75ce3dda62237c45", size = 362071, upload-time = "2025-06-19T17:12:44.483Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/2b/34cc11786bc00d0f04d0f5fdc3a2b1ae0b6239eef72d3d345805f9ad92a1/markdown-3.8.2-py3-none-any.whl", hash = "sha256:5c83764dbd4e00bdd94d85a19b8d55ccca20fe35b2e678a1422b380324dd5f24", size = 106827, upload-time = "2025-06-19T17:12:42.994Z" }, + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, ] [[package]] name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, + { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, + { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, + { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, + { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, + { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] name = "matplotlib" -version = "3.10.5" +version = "3.10.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -1104,62 +1142,62 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/91/f2939bb60b7ebf12478b030e0d7f340247390f402b3b189616aad790c366/matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076", size = 34804044, upload-time = "2025-07-31T18:09:33.805Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/89/5355cdfe43242cb4d1a64a67cb6831398b665ad90e9702c16247cbd8d5ab/matplotlib-3.10.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5d4773a6d1c106ca05cb5a5515d277a6bb96ed09e5c8fab6b7741b8fcaa62c8f", size = 8229094, upload-time = "2025-07-31T18:07:36.507Z" }, - { url = "https://files.pythonhosted.org/packages/34/bc/ba802650e1c69650faed261a9df004af4c6f21759d7a1ec67fe972f093b3/matplotlib-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc88af74e7ba27de6cbe6faee916024ea35d895ed3d61ef6f58c4ce97da7185a", size = 8091464, upload-time = "2025-07-31T18:07:38.864Z" }, - { url = "https://files.pythonhosted.org/packages/ac/64/8d0c8937dee86c286625bddb1902efacc3e22f2b619f5b5a8df29fe5217b/matplotlib-3.10.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:64c4535419d5617f7363dad171a5a59963308e0f3f813c4bed6c9e6e2c131512", size = 8653163, upload-time = "2025-07-31T18:07:41.141Z" }, - { url = "https://files.pythonhosted.org/packages/11/dc/8dfc0acfbdc2fc2336c72561b7935cfa73db9ca70b875d8d3e1b3a6f371a/matplotlib-3.10.5-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a277033048ab22d34f88a3c5243938cef776493f6201a8742ed5f8b553201343", size = 9490635, upload-time = "2025-07-31T18:07:42.936Z" }, - { url = "https://files.pythonhosted.org/packages/54/02/e3fdfe0f2e9fb05f3a691d63876639dbf684170fdcf93231e973104153b4/matplotlib-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4a6470a118a2e93022ecc7d3bd16b3114b2004ea2bf014fff875b3bc99b70c6", size = 9539036, upload-time = "2025-07-31T18:07:45.18Z" }, - { url = "https://files.pythonhosted.org/packages/c1/29/82bf486ff7f4dbedfb11ccc207d0575cbe3be6ea26f75be514252bde3d70/matplotlib-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:7e44cada61bec8833c106547786814dd4a266c1b2964fd25daa3804f1b8d4467", size = 8093529, upload-time = "2025-07-31T18:07:49.553Z" }, - { url = "https://files.pythonhosted.org/packages/aa/c7/1f2db90a1d43710478bb1e9b57b162852f79234d28e4f48a28cc415aa583/matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf", size = 8239216, upload-time = "2025-07-31T18:07:51.947Z" }, - { url = "https://files.pythonhosted.org/packages/82/6d/ca6844c77a4f89b1c9e4d481c412e1d1dbabf2aae2cbc5aa2da4a1d6683e/matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf", size = 8102130, upload-time = "2025-07-31T18:07:53.65Z" }, - { url = "https://files.pythonhosted.org/packages/1d/1e/5e187a30cc673a3e384f3723e5f3c416033c1d8d5da414f82e4e731128ea/matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a", size = 8666471, upload-time = "2025-07-31T18:07:55.304Z" }, - { url = "https://files.pythonhosted.org/packages/03/c0/95540d584d7d645324db99a845ac194e915ef75011a0d5e19e1b5cee7e69/matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc", size = 9500518, upload-time = "2025-07-31T18:07:57.199Z" }, - { url = "https://files.pythonhosted.org/packages/ba/2e/e019352099ea58b4169adb9c6e1a2ad0c568c6377c2b677ee1f06de2adc7/matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89", size = 9552372, upload-time = "2025-07-31T18:07:59.41Z" }, - { url = "https://files.pythonhosted.org/packages/b7/81/3200b792a5e8b354f31f4101ad7834743ad07b6d620259f2059317b25e4d/matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903", size = 8100634, upload-time = "2025-07-31T18:08:01.801Z" }, - { url = "https://files.pythonhosted.org/packages/52/46/a944f6f0c1f5476a0adfa501969d229ce5ae60cf9a663be0e70361381f89/matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420", size = 7978880, upload-time = "2025-07-31T18:08:03.407Z" }, - { url = "https://files.pythonhosted.org/packages/66/1e/c6f6bcd882d589410b475ca1fc22e34e34c82adff519caf18f3e6dd9d682/matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2", size = 8253056, upload-time = "2025-07-31T18:08:05.385Z" }, - { url = "https://files.pythonhosted.org/packages/53/e6/d6f7d1b59413f233793dda14419776f5f443bcccb2dfc84b09f09fe05dbe/matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389", size = 8110131, upload-time = "2025-07-31T18:08:07.293Z" }, - { url = "https://files.pythonhosted.org/packages/66/2b/bed8a45e74957549197a2ac2e1259671cd80b55ed9e1fe2b5c94d88a9202/matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea", size = 8669603, upload-time = "2025-07-31T18:08:09.064Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a7/315e9435b10d057f5e52dfc603cd353167ae28bb1a4e033d41540c0067a4/matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468", size = 9508127, upload-time = "2025-07-31T18:08:10.845Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d9/edcbb1f02ca99165365d2768d517898c22c6040187e2ae2ce7294437c413/matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369", size = 9566926, upload-time = "2025-07-31T18:08:13.186Z" }, - { url = "https://files.pythonhosted.org/packages/3b/d9/6dd924ad5616c97b7308e6320cf392c466237a82a2040381163b7500510a/matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b", size = 8107599, upload-time = "2025-07-31T18:08:15.116Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f3/522dc319a50f7b0279fbe74f86f7a3506ce414bc23172098e8d2bdf21894/matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2", size = 7978173, upload-time = "2025-07-31T18:08:21.518Z" }, - { url = "https://files.pythonhosted.org/packages/8d/05/4f3c1f396075f108515e45cb8d334aff011a922350e502a7472e24c52d77/matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed", size = 8253586, upload-time = "2025-07-31T18:08:23.107Z" }, - { url = "https://files.pythonhosted.org/packages/2f/2c/e084415775aac7016c3719fe7006cdb462582c6c99ac142f27303c56e243/matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1", size = 8110715, upload-time = "2025-07-31T18:08:24.675Z" }, - { url = "https://files.pythonhosted.org/packages/52/1b/233e3094b749df16e3e6cd5a44849fd33852e692ad009cf7de00cf58ddf6/matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7", size = 8669397, upload-time = "2025-07-31T18:08:26.778Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ec/03f9e003a798f907d9f772eed9b7c6a9775d5bd00648b643ebfb88e25414/matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f", size = 9508646, upload-time = "2025-07-31T18:08:28.848Z" }, - { url = "https://files.pythonhosted.org/packages/91/e7/c051a7a386680c28487bca27d23b02d84f63e3d2a9b4d2fc478e6a42e37e/matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4", size = 9567424, upload-time = "2025-07-31T18:08:30.726Z" }, - { url = "https://files.pythonhosted.org/packages/36/c2/24302e93ff431b8f4173ee1dd88976c8d80483cadbc5d3d777cef47b3a1c/matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe", size = 8107809, upload-time = "2025-07-31T18:08:33.928Z" }, - { url = "https://files.pythonhosted.org/packages/0b/33/423ec6a668d375dad825197557ed8fbdb74d62b432c1ed8235465945475f/matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674", size = 7978078, upload-time = "2025-07-31T18:08:36.764Z" }, - { url = "https://files.pythonhosted.org/packages/51/17/521fc16ec766455c7bb52cc046550cf7652f6765ca8650ff120aa2d197b6/matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c", size = 8295590, upload-time = "2025-07-31T18:08:38.521Z" }, - { url = "https://files.pythonhosted.org/packages/f8/12/23c28b2c21114c63999bae129fce7fd34515641c517ae48ce7b7dcd33458/matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e", size = 8158518, upload-time = "2025-07-31T18:08:40.195Z" }, - { url = "https://files.pythonhosted.org/packages/81/f8/aae4eb25e8e7190759f3cb91cbeaa344128159ac92bb6b409e24f8711f78/matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b", size = 8691815, upload-time = "2025-07-31T18:08:42.238Z" }, - { url = "https://files.pythonhosted.org/packages/d0/ba/450c39ebdd486bd33a359fc17365ade46c6a96bf637bbb0df7824de2886c/matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea", size = 9522814, upload-time = "2025-07-31T18:08:44.914Z" }, - { url = "https://files.pythonhosted.org/packages/89/11/9c66f6a990e27bb9aa023f7988d2d5809cb98aa39c09cbf20fba75a542ef/matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124", size = 9573917, upload-time = "2025-07-31T18:08:47.038Z" }, - { url = "https://files.pythonhosted.org/packages/b3/69/8b49394de92569419e5e05e82e83df9b749a0ff550d07631ea96ed2eb35a/matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce", size = 8181034, upload-time = "2025-07-31T18:08:48.943Z" }, - { url = "https://files.pythonhosted.org/packages/47/23/82dc435bb98a2fc5c20dffcac8f0b083935ac28286413ed8835df40d0baa/matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154", size = 8023337, upload-time = "2025-07-31T18:08:50.791Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e0/26b6cfde31f5383503ee45dcb7e691d45dadf0b3f54639332b59316a97f8/matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715", size = 8253591, upload-time = "2025-07-31T18:08:53.254Z" }, - { url = "https://files.pythonhosted.org/packages/c1/89/98488c7ef7ea20ea659af7499628c240a608b337af4be2066d644cfd0a0f/matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837", size = 8112566, upload-time = "2025-07-31T18:08:55.116Z" }, - { url = "https://files.pythonhosted.org/packages/52/67/42294dfedc82aea55e1a767daf3263aacfb5a125f44ba189e685bab41b6f/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202", size = 9513281, upload-time = "2025-07-31T18:08:56.885Z" }, - { url = "https://files.pythonhosted.org/packages/e7/68/f258239e0cf34c2cbc816781c7ab6fca768452e6bf1119aedd2bd4a882a3/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb", size = 9780873, upload-time = "2025-07-31T18:08:59.241Z" }, - { url = "https://files.pythonhosted.org/packages/89/64/f4881554006bd12e4558bd66778bdd15d47b00a1f6c6e8b50f6208eda4b3/matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975", size = 9568954, upload-time = "2025-07-31T18:09:01.244Z" }, - { url = "https://files.pythonhosted.org/packages/06/f8/42779d39c3f757e1f012f2dda3319a89fb602bd2ef98ce8faf0281f4febd/matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667", size = 8237465, upload-time = "2025-07-31T18:09:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/cf/f8/153fd06b5160f0cd27c8b9dd797fcc9fb56ac6a0ebf3c1f765b6b68d3c8a/matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516", size = 8108898, upload-time = "2025-07-31T18:09:05.231Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ee/c4b082a382a225fe0d2a73f1f57cf6f6f132308805b493a54c8641006238/matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e", size = 8295636, upload-time = "2025-07-31T18:09:07.306Z" }, - { url = "https://files.pythonhosted.org/packages/30/73/2195fa2099718b21a20da82dfc753bf2af58d596b51aefe93e359dd5915a/matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a", size = 8158575, upload-time = "2025-07-31T18:09:09.083Z" }, - { url = "https://files.pythonhosted.org/packages/f6/e9/a08cdb34618a91fa08f75e6738541da5cacde7c307cea18ff10f0d03fcff/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569", size = 9522815, upload-time = "2025-07-31T18:09:11.191Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/34d8b7e0d1bb6d06ef45db01dfa560d5a67b1c40c0b998ce9ccde934bb09/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012", size = 9783514, upload-time = "2025-07-31T18:09:13.307Z" }, - { url = "https://files.pythonhosted.org/packages/12/09/d330d1e55dcca2e11b4d304cc5227f52e2512e46828d6249b88e0694176e/matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592", size = 9573932, upload-time = "2025-07-31T18:09:15.335Z" }, - { url = "https://files.pythonhosted.org/packages/eb/3b/f70258ac729aa004aca673800a53a2b0a26d49ca1df2eaa03289a1c40f81/matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959", size = 8322003, upload-time = "2025-07-31T18:09:17.416Z" }, - { url = "https://files.pythonhosted.org/packages/5b/60/3601f8ce6d76a7c81c7f25a0e15fde0d6b66226dd187aa6d2838e6374161/matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b", size = 8153849, upload-time = "2025-07-31T18:09:19.673Z" }, - { url = "https://files.pythonhosted.org/packages/e4/eb/7d4c5de49eb78294e1a8e2be8a6ecff8b433e921b731412a56cd1abd3567/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b5fa2e941f77eb579005fb804026f9d0a1082276118d01cc6051d0d9626eaa7f", size = 8222360, upload-time = "2025-07-31T18:09:21.813Z" }, - { url = "https://files.pythonhosted.org/packages/16/8a/e435db90927b66b16d69f8f009498775f4469f8de4d14b87856965e58eba/matplotlib-3.10.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1fc0d2a3241cdcb9daaca279204a3351ce9df3c0e7e621c7e04ec28aaacaca30", size = 8087462, upload-time = "2025-07-31T18:09:23.504Z" }, - { url = "https://files.pythonhosted.org/packages/0b/dd/06c0e00064362f5647f318e00b435be2ff76a1bdced97c5eaf8347311fbe/matplotlib-3.10.5-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8dee65cb1424b7dc982fe87895b5613d4e691cc57117e8af840da0148ca6c1d7", size = 8659802, upload-time = "2025-07-31T18:09:25.256Z" }, - { url = "https://files.pythonhosted.org/packages/dc/d6/e921be4e1a5f7aca5194e1f016cb67ec294548e530013251f630713e456d/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f", size = 8233224, upload-time = "2025-07-31T18:09:27.512Z" }, - { url = "https://files.pythonhosted.org/packages/ec/74/a2b9b04824b9c349c8f1b2d21d5af43fa7010039427f2b133a034cb09e59/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b", size = 8098539, upload-time = "2025-07-31T18:09:29.629Z" }, - { url = "https://files.pythonhosted.org/packages/fc/66/cd29ebc7f6c0d2a15d216fb572573e8fc38bd5d6dec3bd9d7d904c0949f7/matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61", size = 8672192, upload-time = "2025-07-31T18:09:31.407Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/be/a30bd917018ad220c400169fba298f2bb7003c8ccbc0c3e24ae2aacad1e8/matplotlib-3.10.8-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:00270d217d6b20d14b584c521f810d60c5c78406dc289859776550df837dcda7", size = 8239828, upload-time = "2025-12-10T22:55:02.313Z" }, + { url = "https://files.pythonhosted.org/packages/58/27/ca01e043c4841078e82cf6e80a6993dfecd315c3d79f5f3153afbb8e1ec6/matplotlib-3.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b3c1cc42aa184b3f738cfa18c1c1d72fd496d85467a6cf7b807936d39aa656", size = 8128050, upload-time = "2025-12-10T22:55:04.997Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7ab67f2b729ae6a91bcf9dcac0affb95fb8c56f7fd2b2af894ae0b0cf6fa/matplotlib-3.10.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee40c27c795bda6a5292e9cff9890189d32f7e3a0bf04e0e3c9430c4a00c37df", size = 8700452, upload-time = "2025-12-10T22:55:07.47Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/2d5817b0acee3c49b7e7ccfbf5b273f284957cc8e270adf36375db353190/matplotlib-3.10.8-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a48f2b74020919552ea25d222d5cc6af9ca3f4eb43a93e14d068457f545c2a17", size = 9534928, upload-time = "2025-12-10T22:55:10.566Z" }, + { url = "https://files.pythonhosted.org/packages/c9/5b/8e66653e9f7c39cb2e5cab25fce4810daffa2bff02cbf5f3077cea9e942c/matplotlib-3.10.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f254d118d14a7f99d616271d6c3c27922c092dac11112670b157798b89bf4933", size = 9586377, upload-time = "2025-12-10T22:55:12.362Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/fd0bbadf837f81edb0d208ba8f8cb552874c3b16e27cb91a31977d90875d/matplotlib-3.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9b587c9c7274c1613a30afabf65a272114cd6cdbe67b3406f818c79d7ab2e2a", size = 8128127, upload-time = "2025-12-10T22:55:14.436Z" }, + { url = "https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160", size = 8251215, upload-time = "2025-12-10T22:55:16.175Z" }, + { url = "https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78", size = 8139625, upload-time = "2025-12-10T22:55:17.712Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4", size = 8712614, upload-time = "2025-12-10T22:55:20.8Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f4/b8347351da9a5b3f41e26cf547252d861f685c6867d179a7c9d60ad50189/matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2", size = 9540997, upload-time = "2025-12-10T22:55:23.258Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c0/c7b914e297efe0bc36917bf216b2acb91044b91e930e878ae12981e461e5/matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6", size = 9596825, upload-time = "2025-12-10T22:55:25.217Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9", size = 8135090, upload-time = "2025-12-10T22:55:27.162Z" }, + { url = "https://files.pythonhosted.org/packages/89/dd/a0b6588f102beab33ca6f5218b31725216577b2a24172f327eaf6417d5c9/matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2", size = 8012377, upload-time = "2025-12-10T22:55:29.185Z" }, + { url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a", size = 8260453, upload-time = "2025-12-10T22:55:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58", size = 8148321, upload-time = "2025-12-10T22:55:33.265Z" }, + { url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04", size = 8716944, upload-time = "2025-12-10T22:55:34.922Z" }, + { url = "https://files.pythonhosted.org/packages/00/f9/7638f5cc82ec8a7aa005de48622eecc3ed7c9854b96ba15bd76b7fd27574/matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f", size = 9550099, upload-time = "2025-12-10T22:55:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/78cd5920d35b29fd2a0fe894de8adf672ff52939d2e9b43cb83cd5ce1bc7/matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466", size = 9613040, upload-time = "2025-12-10T22:55:38.715Z" }, + { url = "https://files.pythonhosted.org/packages/30/4e/c10f171b6e2f44d9e3a2b96efa38b1677439d79c99357600a62cc1e9594e/matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf", size = 8142717, upload-time = "2025-12-10T22:55:41.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/76/934db220026b5fef85f45d51a738b91dea7d70207581063cd9bd8fafcf74/matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b", size = 8012751, upload-time = "2025-12-10T22:55:42.684Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6", size = 8261076, upload-time = "2025-12-10T22:55:44.648Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1", size = 8148794, upload-time = "2025-12-10T22:55:46.252Z" }, + { url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486", size = 8718474, upload-time = "2025-12-10T22:55:47.864Z" }, + { url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce", size = 9549637, upload-time = "2025-12-10T22:55:50.048Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6", size = 9613678, upload-time = "2025-12-10T22:55:52.21Z" }, + { url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149", size = 8142686, upload-time = "2025-12-10T22:55:54.253Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645", size = 8012917, upload-time = "2025-12-10T22:55:56.268Z" }, + { url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077", size = 8305679, upload-time = "2025-12-10T22:55:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22", size = 8198336, upload-time = "2025-12-10T22:55:59.371Z" }, + { url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39", size = 8731653, upload-time = "2025-12-10T22:56:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565", size = 9561356, upload-time = "2025-12-10T22:56:02.95Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a", size = 9614000, upload-time = "2025-12-10T22:56:05.411Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958", size = 8220043, upload-time = "2025-12-10T22:56:07.551Z" }, + { url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5", size = 8062075, upload-time = "2025-12-10T22:56:09.178Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f", size = 8262481, upload-time = "2025-12-10T22:56:10.885Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b", size = 8151473, upload-time = "2025-12-10T22:56:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d", size = 9553896, upload-time = "2025-12-10T22:56:14.432Z" }, + { url = "https://files.pythonhosted.org/packages/f5/26/4221a741eb97967bc1fd5e4c52b9aa5a91b2f4ec05b59f6def4d820f9df9/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008", size = 9824193, upload-time = "2025-12-10T22:56:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c", size = 9615444, upload-time = "2025-12-10T22:56:18.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11", size = 8272719, upload-time = "2025-12-10T22:56:20.366Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8", size = 8144205, upload-time = "2025-12-10T22:56:22.239Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50", size = 8305785, upload-time = "2025-12-10T22:56:24.218Z" }, + { url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908", size = 8198361, upload-time = "2025-12-10T22:56:26.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a", size = 9561357, upload-time = "2025-12-10T22:56:28.953Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3d/b5c5d5d5be8ce63292567f0e2c43dde9953d3ed86ac2de0a72e93c8f07a1/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1", size = 9823610, upload-time = "2025-12-10T22:56:31.455Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" }, + { url = "https://files.pythonhosted.org/packages/f5/43/31d59500bb950b0d188e149a2e552040528c13d6e3d6e84d0cccac593dcd/matplotlib-3.10.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f97aeb209c3d2511443f8797e3e5a569aebb040d4f8bc79aa3ee78a8fb9e3dd8", size = 8237252, upload-time = "2025-12-10T22:56:39.529Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2c/615c09984f3c5f907f51c886538ad785cf72e0e11a3225de2c0f9442aecc/matplotlib-3.10.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb061f596dad3a0f52b60dc6a5dec4a0c300dec41e058a7efe09256188d170b7", size = 8124693, upload-time = "2025-12-10T22:56:41.758Z" }, + { url = "https://files.pythonhosted.org/packages/91/e1/2757277a1c56041e1fc104b51a0f7b9a4afc8eb737865d63cababe30bc61/matplotlib-3.10.8-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12d90df9183093fcd479f4172ac26b322b1248b15729cb57f42f71f24c7e37a3", size = 8702205, upload-time = "2025-12-10T22:56:43.415Z" }, + { url = "https://files.pythonhosted.org/packages/04/30/3afaa31c757f34b7725ab9d2ba8b48b5e89c2019c003e7d0ead143aabc5a/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1", size = 8249198, upload-time = "2025-12-10T22:56:45.584Z" }, + { url = "https://files.pythonhosted.org/packages/48/2f/6334aec331f57485a642a7c8be03cb286f29111ae71c46c38b363230063c/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a", size = 8136817, upload-time = "2025-12-10T22:56:47.339Z" }, + { url = "https://files.pythonhosted.org/packages/73/e4/6d6f14b2a759c622f191b2d67e9075a3f56aaccb3be4bb9bb6890030d0a0/matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2", size = 8713867, upload-time = "2025-12-10T22:56:48.954Z" }, ] [[package]] @@ -1223,22 +1261,22 @@ wheels = [ [[package]] name = "mkdocs-git-revision-date-localized-plugin" -version = "1.4.7" +version = "1.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, { name = "gitpython" }, { name = "mkdocs" }, - { name = "pytz" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/f8/a17ec39a4fc314d40cc96afdc1d401e393ebd4f42309d454cc940a2cf38a/mkdocs_git_revision_date_localized_plugin-1.4.7.tar.gz", hash = "sha256:10a49eff1e1c3cb766e054b9d8360c904ce4fe8c33ac3f6cc083ac6459c91953", size = 450473, upload-time = "2025-05-28T18:26:20.697Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/c5/1d3c4e6ddae6230b89d09105cb79de711655e3ebd6745f7a92efea0f5160/mkdocs_git_revision_date_localized_plugin-1.5.0.tar.gz", hash = "sha256:17345ccfdf69a1905dc96fb1070dce82d03a1eb6b0d48f958081a7589ce3c248", size = 460697, upload-time = "2025-10-31T16:11:34.44Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/b6/106fcc15287e7228658fbd0ad9e8b0d775becced0a089cc39984641f4a0f/mkdocs_git_revision_date_localized_plugin-1.4.7-py3-none-any.whl", hash = "sha256:056c0a90242409148f1dc94d5c9d2c25b5b8ddd8de45489fa38f7fa7ccad2bc4", size = 25382, upload-time = "2025-05-28T18:26:18.907Z" }, + { url = "https://files.pythonhosted.org/packages/bc/51/fe0e3fdb16f6eed65c9459d12bae6a4e1f0bb4e2228cb037e7907b002678/mkdocs_git_revision_date_localized_plugin-1.5.0-py3-none-any.whl", hash = "sha256:933f9e35a8c135b113f21bb57610d82e9b7bcc71dd34fb06a029053c97e99656", size = 26153, upload-time = "2025-10-31T16:11:32.987Z" }, ] [[package]] name = "mkdocs-mermaid2-plugin" -version = "1.2.1" +version = "1.2.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -1248,50 +1286,54 @@ dependencies = [ { name = "requests" }, { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/1a/f580733da1924ebc9b4bb04a34ca63ae62a50b0e62eeb016e78d9dee6d69/mkdocs_mermaid2_plugin-1.2.1.tar.gz", hash = "sha256:9c7694c73a65905ac1578f966e5c193325c4d5a5bc1836727e74ac9f99d0e921", size = 16104, upload-time = "2024-11-02T06:27:36.302Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/6d/308f443a558b6a97ce55782658174c0d07c414405cfc0a44d36ad37e36f9/mkdocs_mermaid2_plugin-1.2.3.tar.gz", hash = "sha256:fb6f901d53e5191e93db78f93f219cad926ccc4d51e176271ca5161b6cc5368c", size = 16220, upload-time = "2025-10-17T19:38:53.047Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/ce/c8a41cb0f3044990c8afbdc20c853845a9e940995d4e0cffecafbb5e927b/mkdocs_mermaid2_plugin-1.2.1-py3-none-any.whl", hash = "sha256:22d2cf2c6867d4959a5e0903da2dde78d74581fc0b107b791bc4c7ceb9ce9741", size = 17260, upload-time = "2024-11-02T06:27:34.652Z" }, + { url = "https://files.pythonhosted.org/packages/1a/4b/6fd6dd632019b7f522f1b1f794ab6115cd79890330986614be56fd18f0eb/mkdocs_mermaid2_plugin-1.2.3-py3-none-any.whl", hash = "sha256:33f60c582be623ed53829a96e19284fc7f1b74a1dbae78d4d2e47fe00c3e190d", size = 17299, upload-time = "2025-10-17T19:38:51.874Z" }, ] [[package]] name = "ml-dtypes" -version = "0.5.3" +version = "0.5.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/a7/aad060393123cfb383956dca68402aff3db1e1caffd5764887ed5153f41b/ml_dtypes-0.5.3.tar.gz", hash = "sha256:95ce33057ba4d05df50b1f3cfefab22e351868a843b3b15a46c65836283670c9", size = 692316, upload-time = "2025-07-29T18:39:19.454Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/bb/1f32124ab6d3a279ea39202fe098aea95b2d81ef0ce1d48612b6bf715e82/ml_dtypes-0.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a1d68a7cb53e3f640b2b6a34d12c0542da3dd935e560fdf463c0c77f339fc20", size = 667409, upload-time = "2025-07-29T18:38:17.321Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ac/e002d12ae19136e25bb41c7d14d7e1a1b08f3c0e99a44455ff6339796507/ml_dtypes-0.5.3-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cd5a6c711b5350f3cbc2ac28def81cd1c580075ccb7955e61e9d8f4bfd40d24", size = 4960702, upload-time = "2025-07-29T18:38:19.616Z" }, - { url = "https://files.pythonhosted.org/packages/dd/12/79e9954e6b3255a4b1becb191a922d6e2e94d03d16a06341ae9261963ae8/ml_dtypes-0.5.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdcf26c2dbc926b8a35ec8cbfad7eff1a8bd8239e12478caca83a1fc2c400dc2", size = 4933471, upload-time = "2025-07-29T18:38:21.809Z" }, - { url = "https://files.pythonhosted.org/packages/d5/aa/d1eff619e83cd1ddf6b561d8240063d978e5d887d1861ba09ef01778ec3a/ml_dtypes-0.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:aecbd7c5272c82e54d5b99d8435fd10915d1bc704b7df15e4d9ca8dc3902be61", size = 206330, upload-time = "2025-07-29T18:38:23.663Z" }, - { url = "https://files.pythonhosted.org/packages/af/f1/720cb1409b5d0c05cff9040c0e9fba73fa4c67897d33babf905d5d46a070/ml_dtypes-0.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4a177b882667c69422402df6ed5c3428ce07ac2c1f844d8a1314944651439458", size = 667412, upload-time = "2025-07-29T18:38:25.275Z" }, - { url = "https://files.pythonhosted.org/packages/6a/d5/05861ede5d299f6599f86e6bc1291714e2116d96df003cfe23cc54bcc568/ml_dtypes-0.5.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9849ce7267444c0a717c80c6900997de4f36e2815ce34ac560a3edb2d9a64cd2", size = 4964606, upload-time = "2025-07-29T18:38:27.045Z" }, - { url = "https://files.pythonhosted.org/packages/db/dc/72992b68de367741bfab8df3b3fe7c29f982b7279d341aa5bf3e7ef737ea/ml_dtypes-0.5.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3f5ae0309d9f888fd825c2e9d0241102fadaca81d888f26f845bc8c13c1e4ee", size = 4938435, upload-time = "2025-07-29T18:38:29.193Z" }, - { url = "https://files.pythonhosted.org/packages/81/1c/d27a930bca31fb07d975a2d7eaf3404f9388114463b9f15032813c98f893/ml_dtypes-0.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:58e39349d820b5702bb6f94ea0cb2dc8ec62ee81c0267d9622067d8333596a46", size = 206334, upload-time = "2025-07-29T18:38:30.687Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d8/6922499effa616012cb8dc445280f66d100a7ff39b35c864cfca019b3f89/ml_dtypes-0.5.3-cp311-cp311-win_arm64.whl", hash = "sha256:66c2756ae6cfd7f5224e355c893cfd617fa2f747b8bbd8996152cbdebad9a184", size = 157584, upload-time = "2025-07-29T18:38:32.187Z" }, - { url = "https://files.pythonhosted.org/packages/0d/eb/bc07c88a6ab002b4635e44585d80fa0b350603f11a2097c9d1bfacc03357/ml_dtypes-0.5.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:156418abeeda48ea4797db6776db3c5bdab9ac7be197c1233771e0880c304057", size = 663864, upload-time = "2025-07-29T18:38:33.777Z" }, - { url = "https://files.pythonhosted.org/packages/cf/89/11af9b0f21b99e6386b6581ab40fb38d03225f9de5f55cf52097047e2826/ml_dtypes-0.5.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1db60c154989af253f6c4a34e8a540c2c9dce4d770784d426945e09908fbb177", size = 4951313, upload-time = "2025-07-29T18:38:36.45Z" }, - { url = "https://files.pythonhosted.org/packages/d8/a9/b98b86426c24900b0c754aad006dce2863df7ce0bb2bcc2c02f9cc7e8489/ml_dtypes-0.5.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1b255acada256d1fa8c35ed07b5f6d18bc21d1556f842fbc2d5718aea2cd9e55", size = 4928805, upload-time = "2025-07-29T18:38:38.29Z" }, - { url = "https://files.pythonhosted.org/packages/50/c1/85e6be4fc09c6175f36fb05a45917837f30af9a5146a5151cb3a3f0f9e09/ml_dtypes-0.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:da65e5fd3eea434ccb8984c3624bc234ddcc0d9f4c81864af611aaebcc08a50e", size = 208182, upload-time = "2025-07-29T18:38:39.72Z" }, - { url = "https://files.pythonhosted.org/packages/9e/17/cf5326d6867be057f232d0610de1458f70a8ce7b6290e4b4a277ea62b4cd/ml_dtypes-0.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:8bb9cd1ce63096567f5f42851f5843b5a0ea11511e50039a7649619abfb4ba6d", size = 161560, upload-time = "2025-07-29T18:38:41.072Z" }, - { url = "https://files.pythonhosted.org/packages/2d/87/1bcc98a66de7b2455dfb292f271452cac9edc4e870796e0d87033524d790/ml_dtypes-0.5.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5103856a225465371fe119f2fef737402b705b810bd95ad5f348e6e1a6ae21af", size = 663781, upload-time = "2025-07-29T18:38:42.984Z" }, - { url = "https://files.pythonhosted.org/packages/fd/2c/bd2a79ba7c759ee192b5601b675b180a3fd6ccf48ffa27fe1782d280f1a7/ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cae435a68861660af81fa3c5af16b70ca11a17275c5b662d9c6f58294e0f113", size = 4956217, upload-time = "2025-07-29T18:38:44.65Z" }, - { url = "https://files.pythonhosted.org/packages/14/f3/091ba84e5395d7fe5b30c081a44dec881cd84b408db1763ee50768b2ab63/ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6936283b56d74fbec431ca57ce58a90a908fdbd14d4e2d22eea6d72bb208a7b7", size = 4933109, upload-time = "2025-07-29T18:38:46.405Z" }, - { url = "https://files.pythonhosted.org/packages/bc/24/054036dbe32c43295382c90a1363241684c4d6aaa1ecc3df26bd0c8d5053/ml_dtypes-0.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:d0f730a17cf4f343b2c7ad50cee3bd19e969e793d2be6ed911f43086460096e4", size = 208187, upload-time = "2025-07-29T18:38:48.24Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3d/7dc3ec6794a4a9004c765e0c341e32355840b698f73fd2daff46f128afc1/ml_dtypes-0.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:2db74788fc01914a3c7f7da0763427280adfc9cd377e9604b6b64eb8097284bd", size = 161559, upload-time = "2025-07-29T18:38:50.493Z" }, - { url = "https://files.pythonhosted.org/packages/12/91/e6c7a0d67a152b9330445f9f0cf8ae6eee9b83f990b8c57fe74631e42a90/ml_dtypes-0.5.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:93c36a08a6d158db44f2eb9ce3258e53f24a9a4a695325a689494f0fdbc71770", size = 689321, upload-time = "2025-07-29T18:38:52.03Z" }, - { url = "https://files.pythonhosted.org/packages/9e/6c/b7b94b84a104a5be1883305b87d4c6bd6ae781504474b4cca067cb2340ec/ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0e44a3761f64bc009d71ddb6d6c71008ba21b53ab6ee588dadab65e2fa79eafc", size = 5274495, upload-time = "2025-07-29T18:38:53.797Z" }, - { url = "https://files.pythonhosted.org/packages/5b/38/6266604dffb43378055394ea110570cf261a49876fc48f548dfe876f34cc/ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdf40d2aaabd3913dec11840f0d0ebb1b93134f99af6a0a4fd88ffe924928ab4", size = 5285422, upload-time = "2025-07-29T18:38:56.603Z" }, - { url = "https://files.pythonhosted.org/packages/7c/88/8612ff177d043a474b9408f0382605d881eeb4125ba89d4d4b3286573a83/ml_dtypes-0.5.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:aec640bd94c4c85c0d11e2733bd13cbb10438fb004852996ec0efbc6cacdaf70", size = 661182, upload-time = "2025-07-29T18:38:58.414Z" }, - { url = "https://files.pythonhosted.org/packages/6f/2b/0569a5e88b29240d373e835107c94ae9256fb2191d3156b43b2601859eff/ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bda32ce212baa724e03c68771e5c69f39e584ea426bfe1a701cb01508ffc7035", size = 4956187, upload-time = "2025-07-29T18:39:00.611Z" }, - { url = "https://files.pythonhosted.org/packages/51/66/273c2a06ae44562b104b61e6b14444da00061fd87652506579d7eb2c40b1/ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c205cac07d24a29840c163d6469f61069ce4b065518519216297fc2f261f8db9", size = 4930911, upload-time = "2025-07-29T18:39:02.405Z" }, - { url = "https://files.pythonhosted.org/packages/93/ab/606be3e87dc0821bd360c8c1ee46108025c31a4f96942b63907bb441b87d/ml_dtypes-0.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:cd7c0bb22d4ff86d65ad61b5dd246812e8993fbc95b558553624c33e8b6903ea", size = 216664, upload-time = "2025-07-29T18:39:03.927Z" }, - { url = "https://files.pythonhosted.org/packages/30/a2/e900690ca47d01dffffd66375c5de8c4f8ced0f1ef809ccd3b25b3e6b8fa/ml_dtypes-0.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:9d55ea7f7baf2aed61bf1872116cefc9d0c3693b45cae3916897ee27ef4b835e", size = 160203, upload-time = "2025-07-29T18:39:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/53/21/783dfb51f40d2660afeb9bccf3612b99f6a803d980d2a09132b0f9d216ab/ml_dtypes-0.5.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:e12e29764a0e66a7a31e9b8bf1de5cc0423ea72979f45909acd4292de834ccd3", size = 689324, upload-time = "2025-07-29T18:39:07.567Z" }, - { url = "https://files.pythonhosted.org/packages/09/f7/a82d249c711abf411ac027b7163f285487f5e615c3e0716c61033ce996ab/ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19f6c3a4f635c2fc9e2aa7d91416bd7a3d649b48350c51f7f715a09370a90d93", size = 5275917, upload-time = "2025-07-29T18:39:09.339Z" }, - { url = "https://files.pythonhosted.org/packages/7f/3c/541c4b30815ab90ebfbb51df15d0b4254f2f9f1e2b4907ab229300d5e6f2/ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ab039ffb40f3dc0aeeeba84fd6c3452781b5e15bef72e2d10bcb33e4bbffc39", size = 5285284, upload-time = "2025-07-29T18:39:11.532Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/3a/c5b855752a70267ff729c349e650263adb3c206c29d28cc8ea7ace30a1d5/ml_dtypes-0.5.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b95e97e470fe60ed493fd9ae3911d8da4ebac16bd21f87ffa2b7c588bf22ea2c", size = 679735, upload-time = "2025-11-17T22:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/41/79/7433f30ee04bd4faa303844048f55e1eb939131c8e5195a00a96a0939b64/ml_dtypes-0.5.4-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4b801ebe0b477be666696bda493a9be8356f1f0057a57f1e35cd26928823e5a", size = 5051883, upload-time = "2025-11-17T22:31:33.658Z" }, + { url = "https://files.pythonhosted.org/packages/10/b1/8938e8830b0ee2e167fc75a094dea766a1152bde46752cd9bfc57ee78a82/ml_dtypes-0.5.4-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:388d399a2152dd79a3f0456a952284a99ee5c93d3e2f8dfe25977511e0515270", size = 5030369, upload-time = "2025-11-17T22:31:35.595Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a3/51886727bd16e2f47587997b802dd56398692ce8c6c03c2e5bb32ecafe26/ml_dtypes-0.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:4ff7f3e7ca2972e7de850e7b8fcbb355304271e2933dd90814c1cb847414d6e2", size = 210738, upload-time = "2025-11-17T22:31:37.43Z" }, + { url = "https://files.pythonhosted.org/packages/c6/5e/712092cfe7e5eb667b8ad9ca7c54442f21ed7ca8979745f1000e24cf8737/ml_dtypes-0.5.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6c7ecb74c4bd71db68a6bea1edf8da8c34f3d9fe218f038814fd1d310ac76c90", size = 679734, upload-time = "2025-11-17T22:31:39.223Z" }, + { url = "https://files.pythonhosted.org/packages/4f/cf/912146dfd4b5c0eea956836c01dcd2fce6c9c844b2691f5152aca196ce4f/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc11d7e8c44a65115d05e2ab9989d1e045125d7be8e05a071a48bc76eb6d6040", size = 5056165, upload-time = "2025-11-17T22:31:41.071Z" }, + { url = "https://files.pythonhosted.org/packages/a9/80/19189ea605017473660e43762dc853d2797984b3c7bf30ce656099add30c/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19b9a53598f21e453ea2fbda8aa783c20faff8e1eeb0d7ab899309a0053f1483", size = 5034975, upload-time = "2025-11-17T22:31:42.758Z" }, + { url = "https://files.pythonhosted.org/packages/b4/24/70bd59276883fdd91600ca20040b41efd4902a923283c4d6edcb1de128d2/ml_dtypes-0.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:7c23c54a00ae43edf48d44066a7ec31e05fdc2eee0be2b8b50dd1903a1db94bb", size = 210742, upload-time = "2025-11-17T22:31:44.068Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c9/64230ef14e40aa3f1cb254ef623bf812735e6bec7772848d19131111ac0d/ml_dtypes-0.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:557a31a390b7e9439056644cb80ed0735a6e3e3bb09d67fd5687e4b04238d1de", size = 160709, upload-time = "2025-11-17T22:31:46.557Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b8/3c70881695e056f8a32f8b941126cf78775d9a4d7feba8abcb52cb7b04f2/ml_dtypes-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a174837a64f5b16cab6f368171a1a03a27936b31699d167684073ff1c4237dac", size = 676927, upload-time = "2025-11-17T22:31:48.182Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/428ef6881782e5ebb7eca459689448c0394fa0a80bea3aa9262cba5445ea/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7f7c643e8b1320fd958bf098aa7ecf70623a42ec5154e3be3be673f4c34d900", size = 5028464, upload-time = "2025-11-17T22:31:50.135Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cb/28ce52eb94390dda42599c98ea0204d74799e4d8047a0eb559b6fd648056/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ad459e99793fa6e13bd5b7e6792c8f9190b4e5a1b45c63aba14a4d0a7f1d5ff", size = 5009002, upload-time = "2025-11-17T22:31:52.001Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f0/0cfadd537c5470378b1b32bd859cf2824972174b51b873c9d95cfd7475a5/ml_dtypes-0.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:c1a953995cccb9e25a4ae19e34316671e4e2edaebe4cf538229b1fc7109087b7", size = 212222, upload-time = "2025-11-17T22:31:53.742Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/9acc86985bfad8f2c2d30291b27cd2bb4c74cea08695bd540906ed744249/ml_dtypes-0.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:9bad06436568442575beb2d03389aa7456c690a5b05892c471215bfd8cf39460", size = 160793, upload-time = "2025-11-17T22:31:55.358Z" }, + { url = "https://files.pythonhosted.org/packages/d9/a1/4008f14bbc616cfb1ac5b39ea485f9c63031c4634ab3f4cf72e7541f816a/ml_dtypes-0.5.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c760d85a2f82e2bed75867079188c9d18dae2ee77c25a54d60e9cc79be1bc48", size = 676888, upload-time = "2025-11-17T22:31:56.907Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b7/dff378afc2b0d5a7d6cd9d3209b60474d9819d1189d347521e1688a60a53/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce756d3a10d0c4067172804c9cc276ba9cc0ff47af9078ad439b075d1abdc29b", size = 5036993, upload-time = "2025-11-17T22:31:58.497Z" }, + { url = "https://files.pythonhosted.org/packages/eb/33/40cd74219417e78b97c47802037cf2d87b91973e18bb968a7da48a96ea44/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:533ce891ba774eabf607172254f2e7260ba5f57bdd64030c9a4fcfbd99815d0d", size = 5010956, upload-time = "2025-11-17T22:31:59.931Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8b/200088c6859d8221454825959df35b5244fa9bdf263fd0249ac5fb75e281/ml_dtypes-0.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:f21c9219ef48ca5ee78402d5cc831bd58ea27ce89beda894428bc67a52da5328", size = 212224, upload-time = "2025-11-17T22:32:01.349Z" }, + { url = "https://files.pythonhosted.org/packages/8f/75/dfc3775cb36367816e678f69a7843f6f03bd4e2bcd79941e01ea960a068e/ml_dtypes-0.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:35f29491a3e478407f7047b8a4834e4640a77d2737e0b294d049746507af5175", size = 160798, upload-time = "2025-11-17T22:32:02.864Z" }, + { url = "https://files.pythonhosted.org/packages/4f/74/e9ddb35fd1dd43b1106c20ced3f53c2e8e7fc7598c15638e9f80677f81d4/ml_dtypes-0.5.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:304ad47faa395415b9ccbcc06a0350800bc50eda70f0e45326796e27c62f18b6", size = 702083, upload-time = "2025-11-17T22:32:04.08Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/667060b0aed1aa63166b22897fdf16dca9eb704e6b4bbf86848d5a181aa7/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a0df4223b514d799b8a1629c65ddc351b3efa833ccf7f8ea0cf654a61d1e35d", size = 5354111, upload-time = "2025-11-17T22:32:05.546Z" }, + { url = "https://files.pythonhosted.org/packages/40/49/0f8c498a28c0efa5f5c95a9e374c83ec1385ca41d0e85e7cf40e5d519a21/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531eff30e4d368cb6255bc2328d070e35836aa4f282a0fb5f3a0cd7260257298", size = 5366453, upload-time = "2025-11-17T22:32:07.115Z" }, + { url = "https://files.pythonhosted.org/packages/8c/27/12607423d0a9c6bbbcc780ad19f1f6baa2b68b18ce4bddcdc122c4c68dc9/ml_dtypes-0.5.4-cp313-cp313t-win_amd64.whl", hash = "sha256:cb73dccfc991691c444acc8c0012bee8f2470da826a92e3a20bb333b1a7894e6", size = 225612, upload-time = "2025-11-17T22:32:08.615Z" }, + { url = "https://files.pythonhosted.org/packages/e5/80/5a5929e92c72936d5b19872c5fb8fc09327c1da67b3b68c6a13139e77e20/ml_dtypes-0.5.4-cp313-cp313t-win_arm64.whl", hash = "sha256:3bbbe120b915090d9dd1375e4684dd17a20a2491ef25d640a908281da85e73f1", size = 164145, upload-time = "2025-11-17T22:32:09.782Z" }, + { url = "https://files.pythonhosted.org/packages/72/4e/1339dc6e2557a344f5ba5590872e80346f76f6cb2ac3dd16e4666e88818c/ml_dtypes-0.5.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2b857d3af6ac0d39db1de7c706e69c7f9791627209c3d6dedbfca8c7e5faec22", size = 673781, upload-time = "2025-11-17T22:32:11.364Z" }, + { url = "https://files.pythonhosted.org/packages/04/f9/067b84365c7e83bda15bba2b06c6ca250ce27b20630b1128c435fb7a09aa/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:805cef3a38f4eafae3a5bf9ebdcdb741d0bcfd9e1bd90eb54abd24f928cd2465", size = 5036145, upload-time = "2025-11-17T22:32:12.783Z" }, + { url = "https://files.pythonhosted.org/packages/c6/bb/82c7dcf38070b46172a517e2334e665c5bf374a262f99a283ea454bece7c/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14a4fd3228af936461db66faccef6e4f41c1d82fcc30e9f8d58a08916b1d811f", size = 5010230, upload-time = "2025-11-17T22:32:14.38Z" }, + { url = "https://files.pythonhosted.org/packages/e9/93/2bfed22d2498c468f6bcd0d9f56b033eaa19f33320389314c19ef6766413/ml_dtypes-0.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:8c6a2dcebd6f3903e05d51960a8058d6e131fe69f952a5397e5dbabc841b6d56", size = 221032, upload-time = "2025-11-17T22:32:15.763Z" }, + { url = "https://files.pythonhosted.org/packages/76/a3/9c912fe6ea747bb10fe2f8f54d027eb265db05dfb0c6335e3e063e74e6e8/ml_dtypes-0.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:5a0f68ca8fd8d16583dfa7793973feb86f2fbb56ce3966daf9c9f748f52a2049", size = 163353, upload-time = "2025-11-17T22:32:16.932Z" }, + { url = "https://files.pythonhosted.org/packages/cd/02/48aa7d84cc30ab4ee37624a2fd98c56c02326785750cd212bc0826c2f15b/ml_dtypes-0.5.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:bfc534409c5d4b0bf945af29e5d0ab075eae9eecbb549ff8a29280db822f34f9", size = 702085, upload-time = "2025-11-17T22:32:18.175Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e7/85cb99fe80a7a5513253ec7faa88a65306be071163485e9a626fce1b6e84/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2314892cdc3fcf05e373d76d72aaa15fda9fb98625effa73c1d646f331fcecb7", size = 5355358, upload-time = "2025-11-17T22:32:19.7Z" }, + { url = "https://files.pythonhosted.org/packages/79/2b/a826ba18d2179a56e144aef69e57fb2ab7c464ef0b2111940ee8a3a223a2/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d2ffd05a2575b1519dc928c0b93c06339eb67173ff53acb00724502cda231cf", size = 5366332, upload-time = "2025-11-17T22:32:21.193Z" }, + { url = "https://files.pythonhosted.org/packages/84/44/f4d18446eacb20ea11e82f133ea8f86e2bf2891785b67d9da8d0ab0ef525/ml_dtypes-0.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4381fe2f2452a2d7589689693d3162e876b3ddb0a832cde7a414f8e1adf7eab1", size = 236612, upload-time = "2025-11-17T22:32:22.579Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3f/3d42e9a78fe5edf792a83c074b13b9b770092a4fbf3462872f4303135f09/ml_dtypes-0.5.4-cp314-cp314t-win_arm64.whl", hash = "sha256:11942cbf2cf92157db91e5022633c0d9474d4dfd813a909383bd23ce828a4b7d", size = 168825, upload-time = "2025-11-17T22:32:23.766Z" }, ] [[package]] @@ -1314,9 +1356,7 @@ name = "networkx" version = "3.4.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11'", ] sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload-time = "2024-10-21T12:39:38.695Z" } wheels = [ @@ -1325,22 +1365,16 @@ wheels = [ [[package]] name = "networkx" -version = "3.5" +version = "3.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.13'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] [[package]] @@ -1442,7 +1476,7 @@ name = "nvidia-cudnn-cu12" version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, @@ -1453,7 +1487,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, @@ -1480,9 +1514,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, @@ -1493,7 +1527,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, @@ -1509,10 +1543,10 @@ wheels = [ [[package]] name = "nvidia-nccl-cu12" -version = "2.27.3" +version = "2.27.5" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/5b/4e4fff7bad39adf89f735f2bc87248c81db71205b62bcc0d5ca5b606b3c3/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adf27ccf4238253e0b826bce3ff5fa532d65fc42322c8bfdfaf28024c0fbe039", size = 322364134, upload-time = "2025-06-03T21:58:04.013Z" }, + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, ] [[package]] @@ -1523,6 +1557,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, ] +[[package]] +name = "nvidia-nvshmem-cu12" +version = "3.3.20" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145, upload-time = "2025-08-04T20:25:19.995Z" }, +] + [[package]] name = "nvidia-nvtx-cu12" version = "12.8.90" @@ -1533,7 +1575,7 @@ wheels = [ [[package]] name = "onnx" -version = "1.19.1" +version = "1.20.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ml-dtypes" }, @@ -1541,41 +1583,35 @@ dependencies = [ { name = "protobuf" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/27/2f/c619eb65769357e9b6de9212c9a821ab39cd484448e5d6b3fb5fb0a64c6d/onnx-1.19.1.tar.gz", hash = "sha256:737524d6eb3907d3499ea459c6f01c5a96278bb3a0f2ff8ae04786fb5d7f1ed5", size = 12033525, upload-time = "2025-10-10T04:01:34.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/f3/892eea0206ed13a986239bd508c82b974387ef1b0ffd83ece0ce0725aaf6/onnx-1.19.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:7343250cc5276cf439fe623b8f92e11cf0d1eebc733ae4a8b2e86903bb72ae68", size = 18319433, upload-time = "2025-10-10T03:59:47.236Z" }, - { url = "https://files.pythonhosted.org/packages/9c/f3/c7ea4a1dfda9b9ddeff914a601ffaf5ed151b3352529f223eae74c03c8d1/onnx-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1fb8f79de7f3920bb82b537f3c6ac70c0ce59f600471d9c3eed2b5f8b079b748", size = 18043327, upload-time = "2025-10-10T03:59:50.854Z" }, - { url = "https://files.pythonhosted.org/packages/8d/eb/30159bb6a108b03f2b7521410369a5bd8d296be3fbf0b30ab7acd9ef42ad/onnx-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92b9d2dece41cc84213dbbfd1acbc2a28c27108c53bd28ddb6d1043fbfcbd2d5", size = 18216877, upload-time = "2025-10-10T03:59:54.512Z" }, - { url = "https://files.pythonhosted.org/packages/0c/86/dc034e5a723a20ca45aa8dd76dda53c358a5f955908e1436f42c21bdfb3a/onnx-1.19.1-cp310-cp310-win32.whl", hash = "sha256:c0b1a2b6bb19a0fc9f5de7661a547136d082c03c169a5215e18ff3ececd2a82f", size = 16344116, upload-time = "2025-10-10T03:59:57.991Z" }, - { url = "https://files.pythonhosted.org/packages/b6/60/537f2c19050f71445ee00ed91e78a396b6189dd1fce61b29ac6a0d651c7e/onnx-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:1c0498c00db05fcdb3426697d330dcecc3f60020015065e2c76fa795f2c9a605", size = 16462819, upload-time = "2025-10-10T04:00:01.157Z" }, - { url = "https://files.pythonhosted.org/packages/36/07/0019c72924909e4f64b9199770630ab7b8d7914b912b03230e68f5eda7ae/onnx-1.19.1-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:17aaf5832126de0a5197a5864e4f09a764dd7681d3035135547959b4b6b77a09", size = 18320936, upload-time = "2025-10-10T04:00:04.235Z" }, - { url = "https://files.pythonhosted.org/packages/af/2f/5c47acf740dc35f0decc640844260fbbdc0efa0565657c93fd7ff30f13f3/onnx-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01b292a4d0b197c45d8184545bbc8ae1df83466341b604187c1b05902cb9c920", size = 18044269, upload-time = "2025-10-10T04:00:07.449Z" }, - { url = "https://files.pythonhosted.org/packages/d5/61/6c457ee8c3a62a3cad0a4bfa4c5436bb3ac4df90c3551d40bee1224b5b51/onnx-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1839af08ab4a909e4af936b8149c27f8c64b96138981024e251906e0539d8bf9", size = 18218092, upload-time = "2025-10-10T04:00:11.135Z" }, - { url = "https://files.pythonhosted.org/packages/54/d5/ab832e1369505e67926a70e9a102061f89ad01f91aa296c4b1277cb81b25/onnx-1.19.1-cp311-cp311-win32.whl", hash = "sha256:0bdbb676e3722bd32f9227c465d552689f49086f986a696419d865cb4e70b989", size = 16344809, upload-time = "2025-10-10T04:00:14.634Z" }, - { url = "https://files.pythonhosted.org/packages/8b/b5/6eb4611d24b85002f878ba8476b4cecbe6f9784c0236a3c5eff85236cc0a/onnx-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:1346853df5c1e3ebedb2e794cf2a51e0f33759affd655524864ccbcddad7035b", size = 16464319, upload-time = "2025-10-10T04:00:18.235Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ff/f0e1f06420c70e20d497fec7c94a864d069943b6312bedd4224c0ab946f8/onnx-1.19.1-cp311-cp311-win_arm64.whl", hash = "sha256:2d69c280c0e665b7f923f499243b9bb84fe97970b7a4668afa0032045de602c8", size = 16437503, upload-time = "2025-10-10T04:00:21.247Z" }, - { url = "https://files.pythonhosted.org/packages/50/07/f6c5b2cffef8c29e739616d1415aea22f7b7ef1f19c17f02b7cff71f5498/onnx-1.19.1-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:3612193a89ddbce5c4e86150869b9258780a82fb8c4ca197723a4460178a6ce9", size = 18327840, upload-time = "2025-10-10T04:00:24.259Z" }, - { url = "https://files.pythonhosted.org/packages/93/20/0568ebd52730287ae80cac8ac893a7301c793ea1630984e2519ee92b02a9/onnx-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c2fd2f744e7a3880ad0c262efa2edf6d965d0bd02b8f327ec516ad4cb0f2f15", size = 18042539, upload-time = "2025-10-10T04:00:27.693Z" }, - { url = "https://files.pythonhosted.org/packages/14/fd/cd7a0fd10a04f8cc5ae436b63e0022e236fe51b9dbb8ee6317fd48568c72/onnx-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:485d3674d50d789e0ee72fa6f6e174ab81cb14c772d594f992141bd744729d8a", size = 18218271, upload-time = "2025-10-10T04:00:30.495Z" }, - { url = "https://files.pythonhosted.org/packages/65/68/cc8b8c05469fe08384b446304ad7e6256131ca0463bf6962366eebec98c0/onnx-1.19.1-cp312-cp312-win32.whl", hash = "sha256:638bc56ff1a5718f7441e887aeb4e450f37a81c6eac482040381b140bd9ba601", size = 16345111, upload-time = "2025-10-10T04:00:34.982Z" }, - { url = "https://files.pythonhosted.org/packages/c7/5e/d1cb16693598a512c2cf9ffe0841d8d8fd2c83ae8e889efd554f5aa427cf/onnx-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:bc7e2e4e163e679721e547958b5a7db875bf822cad371b7c1304aa4401a7c7a4", size = 16465621, upload-time = "2025-10-10T04:00:39.107Z" }, - { url = "https://files.pythonhosted.org/packages/90/32/da116cc61fdef334782aa7f87a1738431dd1af1a5d1a44bd95d6d51ad260/onnx-1.19.1-cp312-cp312-win_arm64.whl", hash = "sha256:17c215b1c0f20fe93b4cbe62668247c1d2294b9bc7f6be0ca9ced28e980c07b7", size = 16437505, upload-time = "2025-10-10T04:00:42.255Z" }, - { url = "https://files.pythonhosted.org/packages/b4/b8/ab1fdfe2e8502f4dc4289fc893db35816bd20d080d8370f86e74dda5f598/onnx-1.19.1-cp313-cp313-macosx_12_0_universal2.whl", hash = "sha256:4e5f938c68c4dffd3e19e4fd76eb98d298174eb5ebc09319cdd0ec5fe50050dc", size = 18327815, upload-time = "2025-10-10T04:00:45.682Z" }, - { url = "https://files.pythonhosted.org/packages/04/40/eb875745a4b92aea10e5e32aa2830f409c4d7b6f7b48ca1c4eaad96636c5/onnx-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:86e20a5984b017feeef2dbf4ceff1c7c161ab9423254968dd77d3696c38691d0", size = 18041464, upload-time = "2025-10-10T04:00:48.557Z" }, - { url = "https://files.pythonhosted.org/packages/cf/8e/8586135f40dbe4989cec4d413164bc8fc5c73d37c566f33f5ea3a7f2b6f6/onnx-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d9c467f0f29993c12f330736af87972f30adb8329b515f39d63a0db929cb2c", size = 18218244, upload-time = "2025-10-10T04:00:51.891Z" }, - { url = "https://files.pythonhosted.org/packages/51/b5/4201254b8683129db5da3fb55aa1f7e56d0a8d45c66ce875dec21ca1ff25/onnx-1.19.1-cp313-cp313-win32.whl", hash = "sha256:65eee353a51b4e4ca3e797784661e5376e2b209f17557e04921eac9166a8752e", size = 16345330, upload-time = "2025-10-10T04:00:54.858Z" }, - { url = "https://files.pythonhosted.org/packages/69/67/c6d239afbcdbeb6805432969b908b5c9f700c96d332b34e3f99518d76caf/onnx-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:c3bc87e38b53554b1fc9ef7b275c81c6f5c93c90a91935bb0aa8d4d498a6d48e", size = 16465567, upload-time = "2025-10-10T04:00:57.893Z" }, - { url = "https://files.pythonhosted.org/packages/99/fe/89f1e40f5bc54595ff0dcf5391ce19e578b528973ccc74dd99800196d30d/onnx-1.19.1-cp313-cp313-win_arm64.whl", hash = "sha256:e41496f400afb980ec643d80d5164753a88a85234fa5c06afdeebc8b7d1ec252", size = 16437562, upload-time = "2025-10-10T04:01:00.703Z" }, - { url = "https://files.pythonhosted.org/packages/86/43/b186ccbc8fe7e93643a6a6d40bbf2bb6ce4fb9469bbd3453c77e270c50ad/onnx-1.19.1-cp313-cp313t-macosx_12_0_universal2.whl", hash = "sha256:5f6274abf0fd74e80e78ecbb44bd44509409634525c89a9b38276c8af47dc0a2", size = 18355703, upload-time = "2025-10-10T04:01:03.735Z" }, - { url = "https://files.pythonhosted.org/packages/60/f1/22ee4d8b8f9fa4cb1d1b9579da3b4b5187ddab33846ec5ac744af02c0e2b/onnx-1.19.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:07dcd4d83584eb4bf8f21ac04c82643712e5e93ac2a0ed10121ec123cb127e1e", size = 18047830, upload-time = "2025-10-10T04:01:06.552Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a4/8f3d51e3a095d42cdf2039a590cff06d024f2a10efbd0b1a2a6b3825f019/onnx-1.19.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1975860c3e720db25d37f1619976582828264bdcc64fa7511c321ac4fc01add3", size = 18221126, upload-time = "2025-10-10T04:01:09.77Z" }, - { url = "https://files.pythonhosted.org/packages/4f/0d/f9d6c2237083f1aac14b37f0b03b0d81f1147a8e2af0c3828165e0a6a67b/onnx-1.19.1-cp313-cp313t-win_amd64.whl", hash = "sha256:9807d0e181f6070ee3a6276166acdc571575d1bd522fc7e89dba16fd6e7ffed9", size = 16465560, upload-time = "2025-10-10T04:01:13.212Z" }, - { url = "https://files.pythonhosted.org/packages/36/70/8418a58faa7d606d6a92cab69ae8d361b3b3969bf7e7e9a65a86d5d1b674/onnx-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b6ee83e6929d75005482d9f304c502ac7c9b8d6db153aa6b484dae74d0f28570", size = 18042812, upload-time = "2025-10-10T04:01:15.919Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/bd/bf/824b13b7ea14c2d374b48a296cfa412442e5559326fbab5441a4fcb68924/onnx-1.20.0.tar.gz", hash = "sha256:1a93ec69996b4556062d552ed1aa0671978cfd3c17a40bf4c89a1ae169c6a4ad", size = 12049527, upload-time = "2025-12-01T18:14:34.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/18/8fd768f715a990d3b5786c9bffa6f158934cc1935f2774dd15b26c62f99f/onnx-1.20.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:7e706470f8b731af6d0347c4f01b8e0e1810855d0c71c467066a5bd7fa21704b", size = 18341375, upload-time = "2025-12-01T18:13:29.481Z" }, + { url = "https://files.pythonhosted.org/packages/cf/47/9fdb6e8bde5f77f8bdcf7e584ad88ffa7a189338b92658351518c192bde0/onnx-1.20.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e941d0f3edd57e1d63e2562c74aec2803ead5b965e76ccc3d2b2bd4ae0ea054", size = 17899075, upload-time = "2025-12-01T18:13:32.375Z" }, + { url = "https://files.pythonhosted.org/packages/b2/17/7bb16372f95a8a8251c202018952a747ac7f796a9e6d5720ed7b36680834/onnx-1.20.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6930ed7795912c4298ec8642b33c99c51c026a57edf17788b8451fe22d11e674", size = 18118826, upload-time = "2025-12-01T18:13:35.077Z" }, + { url = "https://files.pythonhosted.org/packages/19/d8/19e3f599601195b1d8ff0bf9e9469065ebeefd9b5e5ec090344f031c38cb/onnx-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f8424c95491de38ecc280f7d467b298cb0b7cdeb1cd892eb9b4b9541c00a600e", size = 16364286, upload-time = "2025-12-01T18:13:38.304Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f9/11d2db50a6c56092bd2e22515fe6998309c7b2389ed67f8ffd27285c33b5/onnx-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:1ecca1f963d69e002c03000f15844f8cac3b6d7b6639a934e73571ee02d59c35", size = 16487791, upload-time = "2025-12-01T18:13:41.062Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9a/125ad5ed919d1782b26b0b4404e51adc44afd029be30d5a81b446dccd9c5/onnx-1.20.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:00dc8ae2c7b283f79623961f450b5515bd2c4b47a7027e7a1374ba49cef27768", size = 18341929, upload-time = "2025-12-01T18:13:43.79Z" }, + { url = "https://files.pythonhosted.org/packages/4d/3c/85280dd05396493f3e1b4feb7a3426715e344b36083229437f31d9788a01/onnx-1.20.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f62978ecfb8f320faba6704abd20253a5a79aacc4e5d39a9c061dd63d3b7574f", size = 17899362, upload-time = "2025-12-01T18:13:46.496Z" }, + { url = "https://files.pythonhosted.org/packages/26/db/e11cf9aaa6ccbcd27ea94d321020fef3207cba388bff96111e6431f97d1a/onnx-1.20.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:71177f8fd5c0dd90697bc281f5035f73707bdac83257a5c54d74403a1100ace9", size = 18119129, upload-time = "2025-12-01T18:13:49.662Z" }, + { url = "https://files.pythonhosted.org/packages/ef/0b/1b99e7ba5ccfa8ecb3509ec579c8520098d09b903ccd520026d60faa7c75/onnx-1.20.0-cp311-cp311-win32.whl", hash = "sha256:1d3d0308e2c194f4b782f51e78461b567fac8ce6871c0cf5452ede261683cc8f", size = 16364604, upload-time = "2025-12-01T18:13:52.691Z" }, + { url = "https://files.pythonhosted.org/packages/51/ab/7399817821d0d18ff67292ac183383e41f4f4ddff2047902f1b7b51d2d40/onnx-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a6de7dda77926c323b0e5a830dc9c2866ce350c1901229e193be1003a076c25", size = 16488019, upload-time = "2025-12-01T18:13:55.776Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/23059c11d9c0fb1951acec504a5cc86e1dd03d2eef3a98cf1941839f5322/onnx-1.20.0-cp311-cp311-win_arm64.whl", hash = "sha256:afc4cf83ce5d547ebfbb276dae8eb0ec836254a8698d462b4ba5f51e717fd1ae", size = 16446841, upload-time = "2025-12-01T18:13:58.091Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/2caa972a31014a8cb4525f715f2a75d93caef9d4b9da2809cc05d0489e43/onnx-1.20.0-cp312-abi3-macosx_12_0_universal2.whl", hash = "sha256:31efe37d7d1d659091f34ddd6a31780334acf7c624176832db9a0a8ececa8fb5", size = 18340913, upload-time = "2025-12-01T18:14:00.477Z" }, + { url = "https://files.pythonhosted.org/packages/78/bb/b98732309f2f6beb4cdcf7b955d7bbfd75a191185370ee21233373db381e/onnx-1.20.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d75da05e743eb9a11ff155a775cae5745e71f1cd0ca26402881b8f20e8d6e449", size = 17896118, upload-time = "2025-12-01T18:14:03.239Z" }, + { url = "https://files.pythonhosted.org/packages/84/a7/38aa564871d062c11538d65c575af9c7e057be880c09ecbd899dd1abfa83/onnx-1.20.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02e0d72ab09a983fce46686b155a5049898558d9f3bc6e8515120d6c40666318", size = 18115415, upload-time = "2025-12-01T18:14:06.261Z" }, + { url = "https://files.pythonhosted.org/packages/3b/17/a600b62cf4ad72976c66f83ce9e324205af434706ad5ec0e35129e125aef/onnx-1.20.0-cp312-abi3-win32.whl", hash = "sha256:392ca68b34b97e172d33b507e1e7bfdf2eea96603e6e7ff109895b82ff009dc7", size = 16363019, upload-time = "2025-12-01T18:14:09.16Z" }, + { url = "https://files.pythonhosted.org/packages/9c/3b/5146ba0a89f73c026bb468c49612bab8d005aa28155ebf06cf5f2eb8d36c/onnx-1.20.0-cp312-abi3-win_amd64.whl", hash = "sha256:259b05758d41645f5545c09f887187662b350d40db8d707c33c94a4f398e1733", size = 16485934, upload-time = "2025-12-01T18:14:13.046Z" }, + { url = "https://files.pythonhosted.org/packages/f3/bc/d251b97395e721b3034e9578d4d4d9fb33aac4197ae16ce8c7ed79a26dce/onnx-1.20.0-cp312-abi3-win_arm64.whl", hash = "sha256:2d25a9e1fde44bc69988e50e2211f62d6afcd01b0fd6dfd23429fd978a35d32f", size = 16444946, upload-time = "2025-12-01T18:14:15.801Z" }, + { url = "https://files.pythonhosted.org/packages/8d/11/4d47409e257013951a17d08c31988e7c2e8638c91d4d5ce18cc57c6ea9d9/onnx-1.20.0-cp313-cp313t-macosx_12_0_universal2.whl", hash = "sha256:7646e700c0a53770a86d5a9a582999a625a3173c4323635960aec3cba8441c6a", size = 18348524, upload-time = "2025-12-01T18:14:18.102Z" }, + { url = "https://files.pythonhosted.org/packages/67/60/774d29a0f00f84a4ec624fe35e0c59e1dbd7f424adaab751977a45b60e05/onnx-1.20.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0bdfd22fe92b87bf98424335ec1191ed79b08cd0f57fe396fab558b83b2c868", size = 17900987, upload-time = "2025-12-01T18:14:20.835Z" }, + { url = "https://files.pythonhosted.org/packages/9c/7c/6bd82b81b85b2680e3de8cf7b6cc49a7380674b121265bb6e1e2ff3bb0aa/onnx-1.20.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1a4e02148b2a7a4b82796d0ecdb6e49ba7abd34bb5a9de22af86aad556fb76", size = 18121332, upload-time = "2025-12-01T18:14:24.558Z" }, + { url = "https://files.pythonhosted.org/packages/d1/42/d2cd00c84def4e17b471e24d82a1d2e3c5be202e2c163420b0353ddf34df/onnx-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2241c85fdaa25a66565fcd1d327c7bcd8f55165420ebaee1e9563c3b9bf961c9", size = 16492660, upload-time = "2025-12-01T18:14:27.456Z" }, + { url = "https://files.pythonhosted.org/packages/42/cd/1106de50a17f2a2dfbb4c8bb3cf2f99be2c7ac2e19abbbf9e07ab47b1b35/onnx-1.20.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ee46cdc5abd851a007a4be81ee53e0e303cf9a0e46d74231d5d361333a1c9411", size = 16448588, upload-time = "2025-12-01T18:14:32.277Z" }, ] [[package]] name = "onnxruntime" -version = "1.22.1" +version = "1.23.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coloredlogs" }, @@ -1586,24 +1622,28 @@ dependencies = [ { name = "sympy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/76/b9/664a1ffee62fa51529fac27b37409d5d28cadee8d97db806fcba68339b7e/onnxruntime-1.22.1-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:80e7f51da1f5201c1379b8d6ef6170505cd800e40da216290f5e06be01aadf95", size = 34319864, upload-time = "2025-07-10T19:15:15.371Z" }, - { url = "https://files.pythonhosted.org/packages/b9/64/bc7221e92c994931024e22b22401b962c299e991558c3d57f7e34538b4b9/onnxruntime-1.22.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89ddfdbbdaf7e3a59515dee657f6515601d55cb21a0f0f48c81aefc54ff1b73", size = 14472246, upload-time = "2025-07-10T19:15:19.403Z" }, - { url = "https://files.pythonhosted.org/packages/84/57/901eddbfb59ac4d008822b236450d5765cafcd450c787019416f8d3baf11/onnxruntime-1.22.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bddc75868bcf6f9ed76858a632f65f7b1846bdcefc6d637b1e359c2c68609964", size = 16459905, upload-time = "2025-07-10T19:15:21.749Z" }, - { url = "https://files.pythonhosted.org/packages/de/90/d6a1eb9b47e66a18afe7d1cf7cf0b2ef966ffa6f44d9f32d94c2be2860fb/onnxruntime-1.22.1-cp310-cp310-win_amd64.whl", hash = "sha256:01e2f21b2793eb0c8642d2be3cee34cc7d96b85f45f6615e4e220424158877ce", size = 12689001, upload-time = "2025-07-10T19:15:23.848Z" }, - { url = "https://files.pythonhosted.org/packages/82/ff/4a1a6747e039ef29a8d4ee4510060e9a805982b6da906a3da2306b7a3be6/onnxruntime-1.22.1-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:f4581bccb786da68725d8eac7c63a8f31a89116b8761ff8b4989dc58b61d49a0", size = 34324148, upload-time = "2025-07-10T19:15:26.584Z" }, - { url = "https://files.pythonhosted.org/packages/0b/05/9f1929723f1cca8c9fb1b2b97ac54ce61362c7201434d38053ea36ee4225/onnxruntime-1.22.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ae7526cf10f93454beb0f751e78e5cb7619e3b92f9fc3bd51aa6f3b7a8977e5", size = 14473779, upload-time = "2025-07-10T19:15:30.183Z" }, - { url = "https://files.pythonhosted.org/packages/59/f3/c93eb4167d4f36ea947930f82850231f7ce0900cb00e1a53dc4995b60479/onnxruntime-1.22.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6effa1299ac549a05c784d50292e3378dbbf010346ded67400193b09ddc2f04", size = 16460799, upload-time = "2025-07-10T19:15:33.005Z" }, - { url = "https://files.pythonhosted.org/packages/a8/01/e536397b03e4462d3260aee5387e6f606c8fa9d2b20b1728f988c3c72891/onnxruntime-1.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:f28a42bb322b4ca6d255531bb334a2b3e21f172e37c1741bd5e66bc4b7b61f03", size = 12689881, upload-time = "2025-07-10T19:15:35.501Z" }, - { url = "https://files.pythonhosted.org/packages/48/70/ca2a4d38a5deccd98caa145581becb20c53684f451e89eb3a39915620066/onnxruntime-1.22.1-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:a938d11c0dc811badf78e435daa3899d9af38abee950d87f3ab7430eb5b3cf5a", size = 34342883, upload-time = "2025-07-10T19:15:38.223Z" }, - { url = "https://files.pythonhosted.org/packages/29/e5/00b099b4d4f6223b610421080d0eed9327ef9986785c9141819bbba0d396/onnxruntime-1.22.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:984cea2a02fcc5dfea44ade9aca9fe0f7a8a2cd6f77c258fc4388238618f3928", size = 14473861, upload-time = "2025-07-10T19:15:42.911Z" }, - { url = "https://files.pythonhosted.org/packages/0a/50/519828a5292a6ccd8d5cd6d2f72c6b36ea528a2ef68eca69647732539ffa/onnxruntime-1.22.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2d39a530aff1ec8d02e365f35e503193991417788641b184f5b1e8c9a6d5ce8d", size = 16475713, upload-time = "2025-07-10T19:15:45.452Z" }, - { url = "https://files.pythonhosted.org/packages/5d/54/7139d463bb0a312890c9a5db87d7815d4a8cce9e6f5f28d04f0b55fcb160/onnxruntime-1.22.1-cp312-cp312-win_amd64.whl", hash = "sha256:6a64291d57ea966a245f749eb970f4fa05a64d26672e05a83fdb5db6b7d62f87", size = 12690910, upload-time = "2025-07-10T19:15:47.478Z" }, - { url = "https://files.pythonhosted.org/packages/e0/39/77cefa829740bd830915095d8408dce6d731b244e24b1f64fe3df9f18e86/onnxruntime-1.22.1-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:d29c7d87b6cbed8fecfd09dca471832384d12a69e1ab873e5effbb94adc3e966", size = 34342026, upload-time = "2025-07-10T19:15:50.266Z" }, - { url = "https://files.pythonhosted.org/packages/d2/a6/444291524cb52875b5de980a6e918072514df63a57a7120bf9dfae3aeed1/onnxruntime-1.22.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:460487d83b7056ba98f1f7bac80287224c31d8149b15712b0d6f5078fcc33d0f", size = 14474014, upload-time = "2025-07-10T19:15:53.991Z" }, - { url = "https://files.pythonhosted.org/packages/87/9d/45a995437879c18beff26eacc2322f4227224d04c6ac3254dce2e8950190/onnxruntime-1.22.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0c37070268ba4e02a1a9d28560cd00cd1e94f0d4f275cbef283854f861a65fa", size = 16475427, upload-time = "2025-07-10T19:15:56.067Z" }, - { url = "https://files.pythonhosted.org/packages/4c/06/9c765e66ad32a7e709ce4cb6b95d7eaa9cb4d92a6e11ea97c20ffecaf765/onnxruntime-1.22.1-cp313-cp313-win_amd64.whl", hash = "sha256:70980d729145a36a05f74b573435531f55ef9503bcda81fc6c3d6b9306199982", size = 12690841, upload-time = "2025-07-10T19:15:58.337Z" }, - { url = "https://files.pythonhosted.org/packages/52/8c/02af24ee1c8dce4e6c14a1642a7a56cebe323d2fa01d9a360a638f7e4b75/onnxruntime-1.22.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33a7980bbc4b7f446bac26c3785652fe8730ed02617d765399e89ac7d44e0f7d", size = 14479333, upload-time = "2025-07-10T19:16:00.544Z" }, - { url = "https://files.pythonhosted.org/packages/5d/15/d75fd66aba116ce3732bb1050401394c5ec52074c4f7ee18db8838dd4667/onnxruntime-1.22.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7e823624b015ea879d976cbef8bfaed2f7e2cc233d7506860a76dd37f8f381", size = 16477261, upload-time = "2025-07-10T19:16:03.226Z" }, + { url = "https://files.pythonhosted.org/packages/35/d6/311b1afea060015b56c742f3531168c1644650767f27ef40062569960587/onnxruntime-1.23.2-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:a7730122afe186a784660f6ec5807138bf9d792fa1df76556b27307ea9ebcbe3", size = 17195934, upload-time = "2025-10-27T23:06:14.143Z" }, + { url = "https://files.pythonhosted.org/packages/db/db/81bf3d7cecfbfed9092b6b4052e857a769d62ed90561b410014e0aae18db/onnxruntime-1.23.2-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:b28740f4ecef1738ea8f807461dd541b8287d5650b5be33bca7b474e3cbd1f36", size = 19153079, upload-time = "2025-10-27T23:05:57.686Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4d/a382452b17cf70a2313153c520ea4c96ab670c996cb3a95cc5d5ac7bfdac/onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f7d1fe034090a1e371b7f3ca9d3ccae2fabae8c1d8844fb7371d1ea38e8e8d2", size = 15219883, upload-time = "2025-10-22T03:46:21.66Z" }, + { url = "https://files.pythonhosted.org/packages/fb/56/179bf90679984c85b417664c26aae4f427cba7514bd2d65c43b181b7b08b/onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4ca88747e708e5c67337b0f65eed4b7d0dd70d22ac332038c9fc4635760018f7", size = 17370357, upload-time = "2025-10-22T03:46:57.968Z" }, + { url = "https://files.pythonhosted.org/packages/cd/6d/738e50c47c2fd285b1e6c8083f15dac1a5f6199213378a5f14092497296d/onnxruntime-1.23.2-cp310-cp310-win_amd64.whl", hash = "sha256:0be6a37a45e6719db5120e9986fcd30ea205ac8103fd1fb74b6c33348327a0cc", size = 13467651, upload-time = "2025-10-27T23:06:11.904Z" }, + { url = "https://files.pythonhosted.org/packages/44/be/467b00f09061572f022ffd17e49e49e5a7a789056bad95b54dfd3bee73ff/onnxruntime-1.23.2-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:6f91d2c9b0965e86827a5ba01531d5b669770b01775b23199565d6c1f136616c", size = 17196113, upload-time = "2025-10-22T03:47:33.526Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a8/3c23a8f75f93122d2b3410bfb74d06d0f8da4ac663185f91866b03f7da1b/onnxruntime-1.23.2-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:87d8b6eaf0fbeb6835a60a4265fde7a3b60157cf1b2764773ac47237b4d48612", size = 19153857, upload-time = "2025-10-22T03:46:37.578Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d8/506eed9af03d86f8db4880a4c47cd0dffee973ef7e4f4cff9f1d4bcf7d22/onnxruntime-1.23.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbfd2fca76c855317568c1b36a885ddea2272c13cb0e395002c402f2360429a6", size = 15220095, upload-time = "2025-10-22T03:46:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/e9/80/113381ba832d5e777accedc6cb41d10f9eca82321ae31ebb6bcede530cea/onnxruntime-1.23.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da44b99206e77734c5819aa2142c69e64f3b46edc3bd314f6a45a932defc0b3e", size = 17372080, upload-time = "2025-10-22T03:47:00.265Z" }, + { url = "https://files.pythonhosted.org/packages/3a/db/1b4a62e23183a0c3fe441782462c0ede9a2a65c6bbffb9582fab7c7a0d38/onnxruntime-1.23.2-cp311-cp311-win_amd64.whl", hash = "sha256:902c756d8b633ce0dedd889b7c08459433fbcf35e9c38d1c03ddc020f0648c6e", size = 13468349, upload-time = "2025-10-22T03:47:25.783Z" }, + { url = "https://files.pythonhosted.org/packages/1b/9e/f748cd64161213adeef83d0cb16cb8ace1e62fa501033acdd9f9341fff57/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:b8f029a6b98d3cf5be564d52802bb50a8489ab73409fa9db0bf583eabb7c2321", size = 17195929, upload-time = "2025-10-22T03:47:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/91/9d/a81aafd899b900101988ead7fb14974c8a58695338ab6a0f3d6b0100f30b/onnxruntime-1.23.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:218295a8acae83905f6f1aed8cacb8e3eb3bd7513a13fe4ba3b2664a19fc4a6b", size = 19157705, upload-time = "2025-10-22T03:46:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/4e40f2fba272a6698d62be2cd21ddc3675edfc1a4b9ddefcc4648f115315/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76ff670550dc23e58ea9bc53b5149b99a44e63b34b524f7b8547469aaa0dcb8c", size = 15226915, upload-time = "2025-10-22T03:46:27.773Z" }, + { url = "https://files.pythonhosted.org/packages/ef/88/9cc25d2bafe6bc0d4d3c1db3ade98196d5b355c0b273e6a5dc09c5d5d0d5/onnxruntime-1.23.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f9b4ae77f8e3c9bee50c27bc1beede83f786fe1d52e99ac85aa8d65a01e9b77", size = 17382649, upload-time = "2025-10-22T03:47:02.782Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b4/569d298f9fc4d286c11c45e85d9ffa9e877af12ace98af8cab52396e8f46/onnxruntime-1.23.2-cp312-cp312-win_amd64.whl", hash = "sha256:25de5214923ce941a3523739d34a520aac30f21e631de53bba9174dc9c004435", size = 13470528, upload-time = "2025-10-22T03:47:28.106Z" }, + { url = "https://files.pythonhosted.org/packages/3d/41/fba0cabccecefe4a1b5fc8020c44febb334637f133acefc7ec492029dd2c/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:2ff531ad8496281b4297f32b83b01cdd719617e2351ffe0dba5684fb283afa1f", size = 17196337, upload-time = "2025-10-22T03:46:35.168Z" }, + { url = "https://files.pythonhosted.org/packages/fe/f9/2d49ca491c6a986acce9f1d1d5fc2099108958cc1710c28e89a032c9cfe9/onnxruntime-1.23.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:162f4ca894ec3de1a6fd53589e511e06ecdc3ff646849b62a9da7489dee9ce95", size = 19157691, upload-time = "2025-10-22T03:46:43.518Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a1/428ee29c6eaf09a6f6be56f836213f104618fb35ac6cc586ff0f477263eb/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45d127d6e1e9b99d1ebeae9bcd8f98617a812f53f46699eafeb976275744826b", size = 15226898, upload-time = "2025-10-22T03:46:30.039Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2b/b57c8a2466a3126dbe0a792f56ad7290949b02f47b86216cd47d857e4b77/onnxruntime-1.23.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8bace4e0d46480fbeeb7bbe1ffe1f080e6663a42d1086ff95c1551f2d39e7872", size = 17382518, upload-time = "2025-10-22T03:47:05.407Z" }, + { url = "https://files.pythonhosted.org/packages/4a/93/aba75358133b3a941d736816dd392f687e7eab77215a6e429879080b76b6/onnxruntime-1.23.2-cp313-cp313-win_amd64.whl", hash = "sha256:1f9cc0a55349c584f083c1c076e611a7c35d5b867d5d6e6d6c823bf821978088", size = 13470276, upload-time = "2025-10-22T03:47:31.193Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3d/6830fa61c69ca8e905f237001dbfc01689a4e4ab06147020a4518318881f/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d2385e774f46ac38f02b3a91a91e30263d41b2f1f4f26ae34805b2a9ddef466", size = 15229610, upload-time = "2025-10-22T03:46:32.239Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ca/862b1e7a639460f0ca25fd5b6135fb42cf9deea86d398a92e44dfda2279d/onnxruntime-1.23.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2b9233c4947907fd1818d0e581c049c41ccc39b2856cc942ff6d26317cee145", size = 17394184, upload-time = "2025-10-22T03:47:08.127Z" }, ] [[package]] @@ -1634,7 +1674,7 @@ wheels = [ [[package]] name = "pandas" -version = "2.3.1" +version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -1642,42 +1682,55 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d1/6f/75aa71f8a14267117adeeed5d21b204770189c0a0025acbdc03c337b28fc/pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2", size = 4487493, upload-time = "2025-07-07T19:20:04.079Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/ca/aa97b47287221fa37a49634532e520300088e290b20d690b21ce3e448143/pandas-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:22c2e866f7209ebc3a8f08d75766566aae02bcc91d196935a1d9e59c7b990ac9", size = 11542731, upload-time = "2025-07-07T19:18:12.619Z" }, - { url = "https://files.pythonhosted.org/packages/80/bf/7938dddc5f01e18e573dcfb0f1b8c9357d9b5fa6ffdee6e605b92efbdff2/pandas-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3583d348546201aff730c8c47e49bc159833f971c2899d6097bce68b9112a4f1", size = 10790031, upload-time = "2025-07-07T19:18:16.611Z" }, - { url = "https://files.pythonhosted.org/packages/ee/2f/9af748366763b2a494fed477f88051dbf06f56053d5c00eba652697e3f94/pandas-2.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f951fbb702dacd390561e0ea45cdd8ecfa7fb56935eb3dd78e306c19104b9b0", size = 11724083, upload-time = "2025-07-07T19:18:20.512Z" }, - { url = "https://files.pythonhosted.org/packages/2c/95/79ab37aa4c25d1e7df953dde407bb9c3e4ae47d154bc0dd1692f3a6dcf8c/pandas-2.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd05b72ec02ebfb993569b4931b2e16fbb4d6ad6ce80224a3ee838387d83a191", size = 12342360, upload-time = "2025-07-07T19:18:23.194Z" }, - { url = "https://files.pythonhosted.org/packages/75/a7/d65e5d8665c12c3c6ff5edd9709d5836ec9b6f80071b7f4a718c6106e86e/pandas-2.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1b916a627919a247d865aed068eb65eb91a344b13f5b57ab9f610b7716c92de1", size = 13202098, upload-time = "2025-07-07T19:18:25.558Z" }, - { url = "https://files.pythonhosted.org/packages/65/f3/4c1dbd754dbaa79dbf8b537800cb2fa1a6e534764fef50ab1f7533226c5c/pandas-2.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fe67dc676818c186d5a3d5425250e40f179c2a89145df477dd82945eaea89e97", size = 13837228, upload-time = "2025-07-07T19:18:28.344Z" }, - { url = "https://files.pythonhosted.org/packages/3f/d6/d7f5777162aa9b48ec3910bca5a58c9b5927cfd9cfde3aa64322f5ba4b9f/pandas-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:2eb789ae0274672acbd3c575b0598d213345660120a257b47b5dafdc618aec83", size = 11336561, upload-time = "2025-07-07T19:18:31.211Z" }, - { url = "https://files.pythonhosted.org/packages/76/1c/ccf70029e927e473a4476c00e0d5b32e623bff27f0402d0a92b7fc29bb9f/pandas-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b", size = 11566608, upload-time = "2025-07-07T19:18:33.86Z" }, - { url = "https://files.pythonhosted.org/packages/ec/d3/3c37cb724d76a841f14b8f5fe57e5e3645207cc67370e4f84717e8bb7657/pandas-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f", size = 10823181, upload-time = "2025-07-07T19:18:36.151Z" }, - { url = "https://files.pythonhosted.org/packages/8a/4c/367c98854a1251940edf54a4df0826dcacfb987f9068abf3e3064081a382/pandas-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85", size = 11793570, upload-time = "2025-07-07T19:18:38.385Z" }, - { url = "https://files.pythonhosted.org/packages/07/5f/63760ff107bcf5146eee41b38b3985f9055e710a72fdd637b791dea3495c/pandas-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d", size = 12378887, upload-time = "2025-07-07T19:18:41.284Z" }, - { url = "https://files.pythonhosted.org/packages/15/53/f31a9b4dfe73fe4711c3a609bd8e60238022f48eacedc257cd13ae9327a7/pandas-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678", size = 13230957, upload-time = "2025-07-07T19:18:44.187Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/6fce6bf85b5056d065e0a7933cba2616dcb48596f7ba3c6341ec4bcc529d/pandas-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299", size = 13883883, upload-time = "2025-07-07T19:18:46.498Z" }, - { url = "https://files.pythonhosted.org/packages/c8/7b/bdcb1ed8fccb63d04bdb7635161d0ec26596d92c9d7a6cce964e7876b6c1/pandas-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab", size = 11340212, upload-time = "2025-07-07T19:18:49.293Z" }, - { url = "https://files.pythonhosted.org/packages/46/de/b8445e0f5d217a99fe0eeb2f4988070908979bec3587c0633e5428ab596c/pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3", size = 11588172, upload-time = "2025-07-07T19:18:52.054Z" }, - { url = "https://files.pythonhosted.org/packages/1e/e0/801cdb3564e65a5ac041ab99ea6f1d802a6c325bb6e58c79c06a3f1cd010/pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232", size = 10717365, upload-time = "2025-07-07T19:18:54.785Z" }, - { url = "https://files.pythonhosted.org/packages/51/a5/c76a8311833c24ae61a376dbf360eb1b1c9247a5d9c1e8b356563b31b80c/pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e", size = 11280411, upload-time = "2025-07-07T19:18:57.045Z" }, - { url = "https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4", size = 11988013, upload-time = "2025-07-07T19:18:59.771Z" }, - { url = "https://files.pythonhosted.org/packages/5b/14/cec7760d7c9507f11c97d64f29022e12a6cc4fc03ac694535e89f88ad2ec/pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8", size = 12767210, upload-time = "2025-07-07T19:19:02.944Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/6e2d2c6728ed29fb3d4d4d302504fb66f1a543e37eb2e43f352a86365cdf/pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679", size = 13440571, upload-time = "2025-07-07T19:19:06.82Z" }, - { url = "https://files.pythonhosted.org/packages/80/a5/3a92893e7399a691bad7664d977cb5e7c81cf666c81f89ea76ba2bff483d/pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8", size = 10987601, upload-time = "2025-07-07T19:19:09.589Z" }, - { url = "https://files.pythonhosted.org/packages/32/ed/ff0a67a2c5505e1854e6715586ac6693dd860fbf52ef9f81edee200266e7/pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22", size = 11531393, upload-time = "2025-07-07T19:19:12.245Z" }, - { url = "https://files.pythonhosted.org/packages/c7/db/d8f24a7cc9fb0972adab0cc80b6817e8bef888cfd0024eeb5a21c0bb5c4a/pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a", size = 10668750, upload-time = "2025-07-07T19:19:14.612Z" }, - { url = "https://files.pythonhosted.org/packages/0f/b0/80f6ec783313f1e2356b28b4fd8d2148c378370045da918c73145e6aab50/pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928", size = 11342004, upload-time = "2025-07-07T19:19:16.857Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e2/20a317688435470872885e7fc8f95109ae9683dec7c50be29b56911515a5/pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9", size = 12050869, upload-time = "2025-07-07T19:19:19.265Z" }, - { url = "https://files.pythonhosted.org/packages/55/79/20d746b0a96c67203a5bee5fb4e00ac49c3e8009a39e1f78de264ecc5729/pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12", size = 12750218, upload-time = "2025-07-07T19:19:21.547Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0f/145c8b41e48dbf03dd18fdd7f24f8ba95b8254a97a3379048378f33e7838/pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb", size = 13416763, upload-time = "2025-07-07T19:19:23.939Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c0/54415af59db5cdd86a3d3bf79863e8cc3fa9ed265f0745254061ac09d5f2/pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956", size = 10987482, upload-time = "2025-07-07T19:19:42.699Z" }, - { url = "https://files.pythonhosted.org/packages/48/64/2fd2e400073a1230e13b8cd604c9bc95d9e3b962e5d44088ead2e8f0cfec/pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a", size = 12029159, upload-time = "2025-07-07T19:19:26.362Z" }, - { url = "https://files.pythonhosted.org/packages/d8/0a/d84fd79b0293b7ef88c760d7dca69828d867c89b6d9bc52d6a27e4d87316/pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9", size = 11393287, upload-time = "2025-07-07T19:19:29.157Z" }, - { url = "https://files.pythonhosted.org/packages/50/ae/ff885d2b6e88f3c7520bb74ba319268b42f05d7e583b5dded9837da2723f/pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275", size = 11309381, upload-time = "2025-07-07T19:19:31.436Z" }, - { url = "https://files.pythonhosted.org/packages/85/86/1fa345fc17caf5d7780d2699985c03dbe186c68fee00b526813939062bb0/pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab", size = 11883998, upload-time = "2025-07-07T19:19:34.267Z" }, - { url = "https://files.pythonhosted.org/packages/81/aa/e58541a49b5e6310d89474333e994ee57fea97c8aaa8fc7f00b873059bbf/pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96", size = 12704705, upload-time = "2025-07-07T19:19:36.856Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f9/07086f5b0f2a19872554abeea7658200824f5835c58a106fa8f2ae96a46c/pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444", size = 13189044, upload-time = "2025-07-07T19:19:39.999Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763, upload-time = "2025-09-29T23:16:53.287Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217, upload-time = "2025-09-29T23:17:04.522Z" }, + { url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791, upload-time = "2025-09-29T23:17:18.444Z" }, + { url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373, upload-time = "2025-09-29T23:17:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444, upload-time = "2025-09-29T23:17:49.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459, upload-time = "2025-09-29T23:18:03.722Z" }, + { url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086, upload-time = "2025-09-29T23:18:18.505Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, + { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, + { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] [[package]] @@ -1691,127 +1744,150 @@ wheels = [ [[package]] name = "pillow" -version = "11.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/5d/45a3553a253ac8763f3561371432a90bdbe6000fbdcf1397ffe502aa206c/pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", size = 5316554, upload-time = "2025-07-01T09:13:39.342Z" }, - { url = "https://files.pythonhosted.org/packages/7c/c8/67c12ab069ef586a25a4a79ced553586748fad100c77c0ce59bb4983ac98/pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", size = 4686548, upload-time = "2025-07-01T09:13:41.835Z" }, - { url = "https://files.pythonhosted.org/packages/2f/bd/6741ebd56263390b382ae4c5de02979af7f8bd9807346d068700dd6d5cf9/pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", size = 5859742, upload-time = "2025-07-03T13:09:47.439Z" }, - { url = "https://files.pythonhosted.org/packages/ca/0b/c412a9e27e1e6a829e6ab6c2dca52dd563efbedf4c9c6aa453d9a9b77359/pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", size = 7633087, upload-time = "2025-07-03T13:09:51.796Z" }, - { url = "https://files.pythonhosted.org/packages/59/9d/9b7076aaf30f5dd17e5e5589b2d2f5a5d7e30ff67a171eb686e4eecc2adf/pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", size = 5963350, upload-time = "2025-07-01T09:13:43.865Z" }, - { url = "https://files.pythonhosted.org/packages/f0/16/1a6bf01fb622fb9cf5c91683823f073f053005c849b1f52ed613afcf8dae/pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", size = 6631840, upload-time = "2025-07-01T09:13:46.161Z" }, - { url = "https://files.pythonhosted.org/packages/7b/e6/6ff7077077eb47fde78739e7d570bdcd7c10495666b6afcd23ab56b19a43/pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", size = 6074005, upload-time = "2025-07-01T09:13:47.829Z" }, - { url = "https://files.pythonhosted.org/packages/c3/3a/b13f36832ea6d279a697231658199e0a03cd87ef12048016bdcc84131601/pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e", size = 6708372, upload-time = "2025-07-01T09:13:52.145Z" }, - { url = "https://files.pythonhosted.org/packages/6c/e4/61b2e1a7528740efbc70b3d581f33937e38e98ef3d50b05007267a55bcb2/pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6", size = 6277090, upload-time = "2025-07-01T09:13:53.915Z" }, - { url = "https://files.pythonhosted.org/packages/a9/d3/60c781c83a785d6afbd6a326ed4d759d141de43aa7365725cbcd65ce5e54/pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f", size = 6985988, upload-time = "2025-07-01T09:13:55.699Z" }, - { url = "https://files.pythonhosted.org/packages/9f/28/4f4a0203165eefb3763939c6789ba31013a2e90adffb456610f30f613850/pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", size = 2422899, upload-time = "2025-07-01T09:13:57.497Z" }, - { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" }, - { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" }, - { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" }, - { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" }, - { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" }, - { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload-time = "2025-07-01T09:14:10.233Z" }, - { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload-time = "2025-07-01T09:14:11.921Z" }, - { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload-time = "2025-07-01T09:14:13.623Z" }, - { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, - { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, - { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, - { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, - { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, - { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, - { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, - { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/6f/8b/209bd6b62ce8367f47e68a218bffac88888fdf2c9fcf1ecadc6c3ec1ebc7/pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", size = 5270556, upload-time = "2025-07-01T09:16:09.961Z" }, - { url = "https://files.pythonhosted.org/packages/2e/e6/231a0b76070c2cfd9e260a7a5b504fb72da0a95279410fa7afd99d9751d6/pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", size = 4654625, upload-time = "2025-07-01T09:16:11.913Z" }, - { url = "https://files.pythonhosted.org/packages/13/f4/10cf94fda33cb12765f2397fc285fa6d8eb9c29de7f3185165b702fc7386/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", size = 4874207, upload-time = "2025-07-03T13:11:10.201Z" }, - { url = "https://files.pythonhosted.org/packages/72/c9/583821097dc691880c92892e8e2d41fe0a5a3d6021f4963371d2f6d57250/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", size = 6583939, upload-time = "2025-07-03T13:11:15.68Z" }, - { url = "https://files.pythonhosted.org/packages/3b/8e/5c9d410f9217b12320efc7c413e72693f48468979a013ad17fd690397b9a/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", size = 4957166, upload-time = "2025-07-01T09:16:13.74Z" }, - { url = "https://files.pythonhosted.org/packages/62/bb/78347dbe13219991877ffb3a91bf09da8317fbfcd4b5f9140aeae020ad71/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", size = 5581482, upload-time = "2025-07-01T09:16:16.107Z" }, - { url = "https://files.pythonhosted.org/packages/d9/28/1000353d5e61498aaeaaf7f1e4b49ddb05f2c6575f9d4f9f914a3538b6e1/pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", size = 6984596, upload-time = "2025-07-01T09:16:18.07Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" }, - { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" }, - { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" }, - { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" }, +version = "12.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/08/26e68b6b5da219c2a2cb7b563af008b53bb8e6b6fcb3fa40715fcdb2523a/pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b", size = 5289809, upload-time = "2025-10-15T18:21:27.791Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/4e58fb097fb74c7b4758a680aacd558810a417d1edaa7000142976ef9d2f/pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1", size = 4650606, upload-time = "2025-10-15T18:21:29.823Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e0/1fa492aa9f77b3bc6d471c468e62bfea1823056bf7e5e4f1914d7ab2565e/pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363", size = 6221023, upload-time = "2025-10-15T18:21:31.415Z" }, + { url = "https://files.pythonhosted.org/packages/c1/09/4de7cd03e33734ccd0c876f0251401f1314e819cbfd89a0fcb6e77927cc6/pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca", size = 8024937, upload-time = "2025-10-15T18:21:33.453Z" }, + { url = "https://files.pythonhosted.org/packages/2e/69/0688e7c1390666592876d9d474f5e135abb4acb39dcb583c4dc5490f1aff/pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e", size = 6334139, upload-time = "2025-10-15T18:21:35.395Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1c/880921e98f525b9b44ce747ad1ea8f73fd7e992bafe3ca5e5644bf433dea/pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782", size = 7026074, upload-time = "2025-10-15T18:21:37.219Z" }, + { url = "https://files.pythonhosted.org/packages/28/03/96f718331b19b355610ef4ebdbbde3557c726513030665071fd025745671/pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10", size = 6448852, upload-time = "2025-10-15T18:21:39.168Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a0/6a193b3f0cc9437b122978d2c5cbce59510ccf9a5b48825096ed7472da2f/pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa", size = 7117058, upload-time = "2025-10-15T18:21:40.997Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c4/043192375eaa4463254e8e61f0e2ec9a846b983929a8d0a7122e0a6d6fff/pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275", size = 6295431, upload-time = "2025-10-15T18:21:42.518Z" }, + { url = "https://files.pythonhosted.org/packages/92/c6/c2f2fc7e56301c21827e689bb8b0b465f1b52878b57471a070678c0c33cd/pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d", size = 7000412, upload-time = "2025-10-15T18:21:44.404Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d2/5f675067ba82da7a1c238a73b32e3fd78d67f9d9f80fbadd33a40b9c0481/pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7", size = 2435903, upload-time = "2025-10-15T18:21:46.29Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/a2f6773b64edb921a756eb0729068acad9fc5208a53f4a349396e9436721/pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc", size = 5289798, upload-time = "2025-10-15T18:21:47.763Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/069b1f8a2e4b5a37493da6c5868531c3f77b85e716ad7a590ef87d58730d/pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257", size = 4650589, upload-time = "2025-10-15T18:21:49.515Z" }, + { url = "https://files.pythonhosted.org/packages/61/e3/2c820d6e9a36432503ead175ae294f96861b07600a7156154a086ba7111a/pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642", size = 6230472, upload-time = "2025-10-15T18:21:51.052Z" }, + { url = "https://files.pythonhosted.org/packages/4f/89/63427f51c64209c5e23d4d52071c8d0f21024d3a8a487737caaf614a5795/pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3", size = 8033887, upload-time = "2025-10-15T18:21:52.604Z" }, + { url = "https://files.pythonhosted.org/packages/f6/1b/c9711318d4901093c15840f268ad649459cd81984c9ec9887756cca049a5/pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c", size = 6343964, upload-time = "2025-10-15T18:21:54.619Z" }, + { url = "https://files.pythonhosted.org/packages/41/1e/db9470f2d030b4995083044cd8738cdd1bf773106819f6d8ba12597d5352/pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227", size = 7034756, upload-time = "2025-10-15T18:21:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b0/6177a8bdd5ee4ed87cba2de5a3cc1db55ffbbec6176784ce5bb75aa96798/pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b", size = 6458075, upload-time = "2025-10-15T18:21:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/bc/5e/61537aa6fa977922c6a03253a0e727e6e4a72381a80d63ad8eec350684f2/pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e", size = 7125955, upload-time = "2025-10-15T18:21:59.372Z" }, + { url = "https://files.pythonhosted.org/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload-time = "2025-10-15T18:22:00.982Z" }, + { url = "https://files.pythonhosted.org/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload-time = "2025-10-15T18:22:02.617Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload-time = "2025-10-15T18:22:04.598Z" }, + { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" }, + { url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload-time = "2025-10-15T18:23:59.594Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload-time = "2025-10-15T18:24:01.669Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload-time = "2025-10-15T18:24:03.403Z" }, + { url = "https://files.pythonhosted.org/packages/94/5a/0d8ab8ffe8a102ff5df60d0de5af309015163bf710c7bb3e8311dd3b3ad0/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c", size = 6986839, upload-time = "2025-10-15T18:24:05.344Z" }, + { url = "https://files.pythonhosted.org/packages/20/2e/3434380e8110b76cd9eb00a363c484b050f949b4bbe84ba770bb8508a02c/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e", size = 5313505, upload-time = "2025-10-15T18:24:07.137Z" }, + { url = "https://files.pythonhosted.org/packages/57/ca/5a9d38900d9d74785141d6580950fe705de68af735ff6e727cb911b64740/pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76", size = 5963654, upload-time = "2025-10-15T18:24:09.579Z" }, + { url = "https://files.pythonhosted.org/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload-time = "2025-10-15T18:24:11.495Z" }, ] [[package]] name = "platformdirs" -version = "4.3.8" +version = "4.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, ] [[package]] name = "protobuf" -version = "6.32.0" +version = "6.33.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/df/fb4a8eeea482eca989b51cffd274aac2ee24e825f0bf3cbce5281fa1567b/protobuf-6.32.0.tar.gz", hash = "sha256:a81439049127067fc49ec1d36e25c6ee1d1a2b7be930675f919258d03c04e7d2", size = 440614, upload-time = "2025-08-14T21:21:25.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/18/df8c87da2e47f4f1dcc5153a81cd6bca4e429803f4069a299e236e4dd510/protobuf-6.32.0-cp310-abi3-win32.whl", hash = "sha256:84f9e3c1ff6fb0308dbacb0950d8aa90694b0d0ee68e75719cb044b7078fe741", size = 424409, upload-time = "2025-08-14T21:21:12.366Z" }, - { url = "https://files.pythonhosted.org/packages/e1/59/0a820b7310f8139bd8d5a9388e6a38e1786d179d6f33998448609296c229/protobuf-6.32.0-cp310-abi3-win_amd64.whl", hash = "sha256:a8bdbb2f009cfc22a36d031f22a625a38b615b5e19e558a7b756b3279723e68e", size = 435735, upload-time = "2025-08-14T21:21:15.046Z" }, - { url = "https://files.pythonhosted.org/packages/cc/5b/0d421533c59c789e9c9894683efac582c06246bf24bb26b753b149bd88e4/protobuf-6.32.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d52691e5bee6c860fff9a1c86ad26a13afbeb4b168cd4445c922b7e2cf85aaf0", size = 426449, upload-time = "2025-08-14T21:21:16.687Z" }, - { url = "https://files.pythonhosted.org/packages/ec/7b/607764ebe6c7a23dcee06e054fd1de3d5841b7648a90fd6def9a3bb58c5e/protobuf-6.32.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:501fe6372fd1c8ea2a30b4d9be8f87955a64d6be9c88a973996cef5ef6f0abf1", size = 322869, upload-time = "2025-08-14T21:21:18.282Z" }, - { url = "https://files.pythonhosted.org/packages/40/01/2e730bd1c25392fc32e3268e02446f0d77cb51a2c3a8486b1798e34d5805/protobuf-6.32.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:75a2aab2bd1aeb1f5dc7c5f33bcb11d82ea8c055c9becbb41c26a8c43fd7092c", size = 322009, upload-time = "2025-08-14T21:21:19.893Z" }, - { url = "https://files.pythonhosted.org/packages/9c/f2/80ffc4677aac1bc3519b26bc7f7f5de7fce0ee2f7e36e59e27d8beb32dd1/protobuf-6.32.0-py3-none-any.whl", hash = "sha256:ba377e5b67b908c8f3072a57b63e2c6a4cbd18aea4ed98d2584350dbf46f2783", size = 169287, upload-time = "2025-08-14T21:21:23.515Z" }, + { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" }, + { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" }, + { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" }, + { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" }, +] + +[[package]] +name = "psutil" +version = "7.1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/88/bdd0a41e5857d5d703287598cbf08dad90aed56774ea52ae071bae9071b6/psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74", size = 489059, upload-time = "2025-11-02T12:25:54.619Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/93/0c49e776b8734fef56ec9c5c57f923922f2cf0497d62e0f419465f28f3d0/psutil-7.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0005da714eee687b4b8decd3d6cc7c6db36215c9e74e5ad2264b90c3df7d92dc", size = 239751, upload-time = "2025-11-02T12:25:58.161Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8d/b31e39c769e70780f007969815195a55c81a63efebdd4dbe9e7a113adb2f/psutil-7.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19644c85dcb987e35eeeaefdc3915d059dac7bd1167cdcdbf27e0ce2df0c08c0", size = 240368, upload-time = "2025-11-02T12:26:00.491Z" }, + { url = "https://files.pythonhosted.org/packages/62/61/23fd4acc3c9eebbf6b6c78bcd89e5d020cfde4acf0a9233e9d4e3fa698b4/psutil-7.1.3-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95ef04cf2e5ba0ab9eaafc4a11eaae91b44f4ef5541acd2ee91d9108d00d59a7", size = 287134, upload-time = "2025-11-02T12:26:02.613Z" }, + { url = "https://files.pythonhosted.org/packages/30/1c/f921a009ea9ceb51aa355cb0cc118f68d354db36eae18174bab63affb3e6/psutil-7.1.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1068c303be3a72f8e18e412c5b2a8f6d31750fb152f9cb106b54090296c9d251", size = 289904, upload-time = "2025-11-02T12:26:05.207Z" }, + { url = "https://files.pythonhosted.org/packages/a6/82/62d68066e13e46a5116df187d319d1724b3f437ddd0f958756fc052677f4/psutil-7.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:18349c5c24b06ac5612c0428ec2a0331c26443d259e2a0144a9b24b4395b58fa", size = 249642, upload-time = "2025-11-02T12:26:07.447Z" }, + { url = "https://files.pythonhosted.org/packages/df/ad/c1cd5fe965c14a0392112f68362cfceb5230819dbb5b1888950d18a11d9f/psutil-7.1.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c525ffa774fe4496282fb0b1187725793de3e7c6b29e41562733cae9ada151ee", size = 245518, upload-time = "2025-11-02T12:26:09.719Z" }, + { url = "https://files.pythonhosted.org/packages/2e/bb/6670bded3e3236eb4287c7bcdc167e9fae6e1e9286e437f7111caed2f909/psutil-7.1.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b403da1df4d6d43973dc004d19cee3b848e998ae3154cc8097d139b77156c353", size = 239843, upload-time = "2025-11-02T12:26:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/b8/66/853d50e75a38c9a7370ddbeefabdd3d3116b9c31ef94dc92c6729bc36bec/psutil-7.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad81425efc5e75da3f39b3e636293360ad8d0b49bed7df824c79764fb4ba9b8b", size = 240369, upload-time = "2025-11-02T12:26:14.358Z" }, + { url = "https://files.pythonhosted.org/packages/41/bd/313aba97cb5bfb26916dc29cf0646cbe4dd6a89ca69e8c6edce654876d39/psutil-7.1.3-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f33a3702e167783a9213db10ad29650ebf383946e91bc77f28a5eb083496bc9", size = 288210, upload-time = "2025-11-02T12:26:16.699Z" }, + { url = "https://files.pythonhosted.org/packages/c2/fa/76e3c06e760927a0cfb5705eb38164254de34e9bd86db656d4dbaa228b04/psutil-7.1.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fac9cd332c67f4422504297889da5ab7e05fd11e3c4392140f7370f4208ded1f", size = 291182, upload-time = "2025-11-02T12:26:18.848Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1d/5774a91607035ee5078b8fd747686ebec28a962f178712de100d00b78a32/psutil-7.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:3792983e23b69843aea49c8f5b8f115572c5ab64c153bada5270086a2123c7e7", size = 250466, upload-time = "2025-11-02T12:26:21.183Z" }, + { url = "https://files.pythonhosted.org/packages/00/ca/e426584bacb43a5cb1ac91fae1937f478cd8fbe5e4ff96574e698a2c77cd/psutil-7.1.3-cp314-cp314t-win_arm64.whl", hash = "sha256:31d77fcedb7529f27bb3a0472bea9334349f9a04160e8e6e5020f22c59893264", size = 245756, upload-time = "2025-11-02T12:26:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab", size = 238359, upload-time = "2025-11-02T12:26:25.284Z" }, + { url = "https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880", size = 239171, upload-time = "2025-11-02T12:26:27.23Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3", size = 263261, upload-time = "2025-11-02T12:26:29.48Z" }, + { url = "https://files.pythonhosted.org/packages/e0/95/992c8816a74016eb095e73585d747e0a8ea21a061ed3689474fabb29a395/psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b", size = 264635, upload-time = "2025-11-02T12:26:31.74Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd", size = 247633, upload-time = "2025-11-02T12:26:33.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ad/33b2ccec09bf96c2b2ef3f9a6f66baac8253d7565d8839e024a6b905d45d/psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1", size = 244608, upload-time = "2025-11-02T12:26:36.136Z" }, ] [[package]] @@ -1837,24 +1913,24 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.16.1" +version = "10.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/b3/6d2b3f149bc5413b0a29761c2c5832d8ce904a1d7f621e86616d96f505cc/pymdown_extensions-10.16.1.tar.gz", hash = "sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91", size = 853277, upload-time = "2025-07-28T16:19:34.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/2d/9f30cee56d4d6d222430d401e85b0a6a1ae229819362f5786943d1a8c03b/pymdown_extensions-10.19.1.tar.gz", hash = "sha256:4969c691009a389fb1f9712dd8e7bd70dcc418d15a0faf70acb5117d022f7de8", size = 847839, upload-time = "2025-12-14T17:25:24.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/06/43084e6cbd4b3bc0e80f6be743b2e79fbc6eed8de9ad8c629939fa55d972/pymdown_extensions-10.16.1-py3-none-any.whl", hash = "sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d", size = 266178, upload-time = "2025-07-28T16:19:31.401Z" }, + { url = "https://files.pythonhosted.org/packages/fb/35/b763e8fbcd51968329b9adc52d188fc97859f85f2ee15fe9f379987d99c5/pymdown_extensions-10.19.1-py3-none-any.whl", hash = "sha256:e8698a66055b1dc0dca2a7f2c9d0ea6f5faa7834a9c432e3535ab96c0c4e509b", size = 266693, upload-time = "2025-12-14T17:25:22.999Z" }, ] [[package]] name = "pyparsing" -version = "3.2.3" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] @@ -1916,46 +1992,66 @@ wheels = [ [[package]] name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] @@ -2045,7 +2141,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.4" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -2053,9 +2149,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -2081,9 +2177,7 @@ name = "scipy" version = "1.15.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11'", ] dependencies = [ { name = "numpy", marker = "python_full_version < '3.11'" }, @@ -2142,15 +2236,9 @@ name = "scipy" version = "1.16.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.13' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version == '3.12.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.13'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", ] dependencies = [ { name = "numpy", marker = "python_full_version >= '3.11'" }, @@ -2263,22 +2351,22 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.7" +version = "2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, ] [[package]] name = "spidev" -version = "3.7" +version = "3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/99/dd50af8200e224ce9412ad01cdbeeb5b39b2d61acd72138f2b92c4a6d619/spidev-3.7.tar.gz", hash = "sha256:ce628a5ff489f45132679879bff5f455a66abf9751af01843850155b06ae92f0", size = 11616, upload-time = "2025-05-06T14:23:30.783Z" } +sdist = { url = "https://files.pythonhosted.org/packages/67/87/039b6eeea781598015b538691bc174cc0bf77df9d4d2d3b8bf9245c0de8c/spidev-3.8.tar.gz", hash = "sha256:2bc02fb8c6312d519ebf1f4331067427c0921d3f77b8bcaf05189a2e8b8382c0", size = 13893, upload-time = "2025-09-15T18:56:20.672Z" } [[package]] name = "stable-baselines3" -version = "2.7.0" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cloudpickle" }, @@ -2288,9 +2376,9 @@ dependencies = [ { name = "pandas" }, { name = "torch" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/cc/9a334071fae143bc7177e17a3191db83c1a4bf9038b09c4c5a34e427ca33/stable_baselines3-2.7.0.tar.gz", hash = "sha256:5258561e5becd15234274262cf09fcb9a082a73c2c67a85322f5652a05195ec4", size = 219012, upload-time = "2025-07-25T09:54:35.113Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/42/f284c28272422262a99cdf35ecd2e283fded2f75327e6d5e82a9f6d6fe62/stable_baselines3-2.7.1.tar.gz", hash = "sha256:cd90d12d9ee0d9584053f12215c1682b313be4e3a8d8007739319799c3d2c071", size = 220719, upload-time = "2025-12-05T11:22:03.691Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/df/6b074e5b8e8437aac0b05e12749565f4613152016daddd45d414269b09d6/stable_baselines3-2.7.0-py3-none-any.whl", hash = "sha256:3de94fab840b3eb379a352c8d9b390998686d2fcb41de36298066935eef94bea", size = 187216, upload-time = "2025-07-25T09:54:30.55Z" }, + { url = "https://files.pythonhosted.org/packages/df/cc/a3038d3833f329dcd03b2dce8b778e4b41044caff88b48429473b8629623/stable_baselines3-2.7.1-py3-none-any.whl", hash = "sha256:b017e76dfe5ca0ce6eabb29e79c42e8c7e125d5862bfcd43ce04ec19732348d0", size = 188039, upload-time = "2025-12-05T11:22:00.819Z" }, ] [[package]] @@ -2322,14 +2410,14 @@ wheels = [ [[package]] name = "torch" -version = "2.8.0" +version = "2.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, { name = "fsspec" }, { name = "jinja2" }, { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, @@ -2343,6 +2431,7 @@ dependencies = [ { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools", marker = "python_full_version >= '3.12'" }, { name = "sympy" }, @@ -2350,68 +2439,75 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/63/28/110f7274254f1b8476c561dada127173f994afa2b1ffc044efb773c15650/torch-2.8.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:0be92c08b44009d4131d1ff7a8060d10bafdb7ddcb7359ef8d8c5169007ea905", size = 102052793, upload-time = "2025-08-06T14:53:15.852Z" }, - { url = "https://files.pythonhosted.org/packages/70/1c/58da560016f81c339ae14ab16c98153d51c941544ae568da3cb5b1ceb572/torch-2.8.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:89aa9ee820bb39d4d72b794345cccef106b574508dd17dbec457949678c76011", size = 888025420, upload-time = "2025-08-06T14:54:18.014Z" }, - { url = "https://files.pythonhosted.org/packages/70/87/f69752d0dd4ba8218c390f0438130c166fa264a33b7025adb5014b92192c/torch-2.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e8e5bf982e87e2b59d932769938b698858c64cc53753894be25629bdf5cf2f46", size = 241363614, upload-time = "2025-08-06T14:53:31.496Z" }, - { url = "https://files.pythonhosted.org/packages/ef/d6/e6d4c57e61c2b2175d3aafbfb779926a2cfd7c32eeda7c543925dceec923/torch-2.8.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:a3f16a58a9a800f589b26d47ee15aca3acf065546137fc2af039876135f4c760", size = 73611154, upload-time = "2025-08-06T14:53:10.919Z" }, - { url = "https://files.pythonhosted.org/packages/8f/c4/3e7a3887eba14e815e614db70b3b529112d1513d9dae6f4d43e373360b7f/torch-2.8.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:220a06fd7af8b653c35d359dfe1aaf32f65aa85befa342629f716acb134b9710", size = 102073391, upload-time = "2025-08-06T14:53:20.937Z" }, - { url = "https://files.pythonhosted.org/packages/5a/63/4fdc45a0304536e75a5e1b1bbfb1b56dd0e2743c48ee83ca729f7ce44162/torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c12fa219f51a933d5f80eeb3a7a5d0cbe9168c0a14bbb4055f1979431660879b", size = 888063640, upload-time = "2025-08-06T14:55:05.325Z" }, - { url = "https://files.pythonhosted.org/packages/84/57/2f64161769610cf6b1c5ed782bd8a780e18a3c9d48931319f2887fa9d0b1/torch-2.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c7ef765e27551b2fbfc0f41bcf270e1292d9bf79f8e0724848b1682be6e80aa", size = 241366752, upload-time = "2025-08-06T14:53:38.692Z" }, - { url = "https://files.pythonhosted.org/packages/a4/5e/05a5c46085d9b97e928f3f037081d3d2b87fb4b4195030fc099aaec5effc/torch-2.8.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:5ae0524688fb6707c57a530c2325e13bb0090b745ba7b4a2cd6a3ce262572916", size = 73621174, upload-time = "2025-08-06T14:53:25.44Z" }, - { url = "https://files.pythonhosted.org/packages/49/0c/2fd4df0d83a495bb5e54dca4474c4ec5f9c62db185421563deeb5dabf609/torch-2.8.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2fab4153768d433f8ed9279c8133a114a034a61e77a3a104dcdf54388838705", size = 101906089, upload-time = "2025-08-06T14:53:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/99/a8/6acf48d48838fb8fe480597d98a0668c2beb02ee4755cc136de92a0a956f/torch-2.8.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2aca0939fb7e4d842561febbd4ffda67a8e958ff725c1c27e244e85e982173c", size = 887913624, upload-time = "2025-08-06T14:56:44.33Z" }, - { url = "https://files.pythonhosted.org/packages/af/8a/5c87f08e3abd825c7dfecef5a0f1d9aa5df5dd0e3fd1fa2f490a8e512402/torch-2.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:2f4ac52f0130275d7517b03a33d2493bab3693c83dcfadf4f81688ea82147d2e", size = 241326087, upload-time = "2025-08-06T14:53:46.503Z" }, - { url = "https://files.pythonhosted.org/packages/be/66/5c9a321b325aaecb92d4d1855421e3a055abd77903b7dab6575ca07796db/torch-2.8.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:619c2869db3ada2c0105487ba21b5008defcc472d23f8b80ed91ac4a380283b0", size = 73630478, upload-time = "2025-08-06T14:53:57.144Z" }, - { url = "https://files.pythonhosted.org/packages/10/4e/469ced5a0603245d6a19a556e9053300033f9c5baccf43a3d25ba73e189e/torch-2.8.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2b2f96814e0345f5a5aed9bf9734efa913678ed19caf6dc2cddb7930672d6128", size = 101936856, upload-time = "2025-08-06T14:54:01.526Z" }, - { url = "https://files.pythonhosted.org/packages/16/82/3948e54c01b2109238357c6f86242e6ecbf0c63a1af46906772902f82057/torch-2.8.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:65616ca8ec6f43245e1f5f296603e33923f4c30f93d65e103d9e50c25b35150b", size = 887922844, upload-time = "2025-08-06T14:55:50.78Z" }, - { url = "https://files.pythonhosted.org/packages/e3/54/941ea0a860f2717d86a811adf0c2cd01b3983bdd460d0803053c4e0b8649/torch-2.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:659df54119ae03e83a800addc125856effda88b016dfc54d9f65215c3975be16", size = 241330968, upload-time = "2025-08-06T14:54:45.293Z" }, - { url = "https://files.pythonhosted.org/packages/de/69/8b7b13bba430f5e21d77708b616f767683629fc4f8037564a177d20f90ed/torch-2.8.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:1a62a1ec4b0498930e2543535cf70b1bef8c777713de7ceb84cd79115f553767", size = 73915128, upload-time = "2025-08-06T14:54:34.769Z" }, - { url = "https://files.pythonhosted.org/packages/15/0e/8a800e093b7f7430dbaefa80075aee9158ec22e4c4fc3c1a66e4fb96cb4f/torch-2.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:83c13411a26fac3d101fe8035a6b0476ae606deb8688e904e796a3534c197def", size = 102020139, upload-time = "2025-08-06T14:54:39.047Z" }, - { url = "https://files.pythonhosted.org/packages/4a/15/5e488ca0bc6162c86a33b58642bc577c84ded17c7b72d97e49b5833e2d73/torch-2.8.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8f0a9d617a66509ded240add3754e462430a6c1fc5589f86c17b433dd808f97a", size = 887990692, upload-time = "2025-08-06T14:56:18.286Z" }, - { url = "https://files.pythonhosted.org/packages/b4/a8/6a04e4b54472fc5dba7ca2341ab219e529f3c07b6941059fbf18dccac31f/torch-2.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a7242b86f42be98ac674b88a4988643b9bc6145437ec8f048fea23f72feb5eca", size = 241603453, upload-time = "2025-08-06T14:55:22.945Z" }, - { url = "https://files.pythonhosted.org/packages/04/6e/650bb7f28f771af0cb791b02348db8b7f5f64f40f6829ee82aa6ce99aabe/torch-2.8.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:7b677e17f5a3e69fdef7eb3b9da72622f8d322692930297e4ccb52fefc6c8211", size = 73632395, upload-time = "2025-08-06T14:55:28.645Z" }, + { url = "https://files.pythonhosted.org/packages/5f/56/9577683b23072075ed2e40d725c52c2019d71a972fab8e083763da8e707e/torch-2.9.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:1cc208435f6c379f9b8fdfd5ceb5be1e3b72a6bdf1cb46c0d2812aa73472db9e", size = 104207681, upload-time = "2025-11-12T15:19:56.48Z" }, + { url = "https://files.pythonhosted.org/packages/38/45/be5a74f221df8f4b609b78ff79dc789b0cc9017624544ac4dd1c03973150/torch-2.9.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:9fd35c68b3679378c11f5eb73220fdcb4e6f4592295277fbb657d31fd053237c", size = 899794036, upload-time = "2025-11-12T15:21:01.886Z" }, + { url = "https://files.pythonhosted.org/packages/67/95/a581e8a382596b69385a44bab2733f1273d45c842f5d4a504c0edc3133b6/torch-2.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:2af70e3be4a13becba4655d6cc07dcfec7ae844db6ac38d6c1dafeb245d17d65", size = 110969861, upload-time = "2025-11-12T15:21:30.145Z" }, + { url = "https://files.pythonhosted.org/packages/ad/51/1756dc128d2bf6ea4e0a915cb89ea5e730315ff33d60c1ff56fd626ba3eb/torch-2.9.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:a83b0e84cc375e3318a808d032510dde99d696a85fe9473fc8575612b63ae951", size = 74452222, upload-time = "2025-11-12T15:20:46.223Z" }, + { url = "https://files.pythonhosted.org/packages/15/db/c064112ac0089af3d2f7a2b5bfbabf4aa407a78b74f87889e524b91c5402/torch-2.9.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:62b3fd888277946918cba4478cf849303da5359f0fb4e3bfb86b0533ba2eaf8d", size = 104220430, upload-time = "2025-11-12T15:20:31.705Z" }, + { url = "https://files.pythonhosted.org/packages/56/be/76eaa36c9cd032d3b01b001e2c5a05943df75f26211f68fae79e62f87734/torch-2.9.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d033ff0ac3f5400df862a51bdde9bad83561f3739ea0046e68f5401ebfa67c1b", size = 899821446, upload-time = "2025-11-12T15:20:15.544Z" }, + { url = "https://files.pythonhosted.org/packages/47/cc/7a2949e38dfe3244c4df21f0e1c27bce8aedd6c604a587dd44fc21017cb4/torch-2.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:0d06b30a9207b7c3516a9e0102114024755a07045f0c1d2f2a56b1819ac06bcb", size = 110973074, upload-time = "2025-11-12T15:21:39.958Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ce/7d251155a783fb2c1bb6837b2b7023c622a2070a0a72726ca1df47e7ea34/torch-2.9.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:52347912d868653e1528b47cafaf79b285b98be3f4f35d5955389b1b95224475", size = 74463887, upload-time = "2025-11-12T15:20:36.611Z" }, + { url = "https://files.pythonhosted.org/packages/0f/27/07c645c7673e73e53ded71705045d6cb5bae94c4b021b03aa8d03eee90ab/torch-2.9.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:da5f6f4d7f4940a173e5572791af238cb0b9e21b1aab592bd8b26da4c99f1cd6", size = 104126592, upload-time = "2025-11-12T15:20:41.62Z" }, + { url = "https://files.pythonhosted.org/packages/19/17/e377a460603132b00760511299fceba4102bd95db1a0ee788da21298ccff/torch-2.9.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:27331cd902fb4322252657f3902adf1c4f6acad9dcad81d8df3ae14c7c4f07c4", size = 899742281, upload-time = "2025-11-12T15:22:17.602Z" }, + { url = "https://files.pythonhosted.org/packages/b1/1a/64f5769025db846a82567fa5b7d21dba4558a7234ee631712ee4771c436c/torch-2.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:81a285002d7b8cfd3fdf1b98aa8df138d41f1a8334fd9ea37511517cedf43083", size = 110940568, upload-time = "2025-11-12T15:21:18.689Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ab/07739fd776618e5882661d04c43f5b5586323e2f6a2d7d84aac20d8f20bd/torch-2.9.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:c0d25d1d8e531b8343bea0ed811d5d528958f1dcbd37e7245bc686273177ad7e", size = 74479191, upload-time = "2025-11-12T15:21:25.816Z" }, + { url = "https://files.pythonhosted.org/packages/20/60/8fc5e828d050bddfab469b3fe78e5ab9a7e53dda9c3bdc6a43d17ce99e63/torch-2.9.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c29455d2b910b98738131990394da3e50eea8291dfeb4b12de71ecf1fdeb21cb", size = 104135743, upload-time = "2025-11-12T15:21:34.936Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/6d3f80e6918213babddb2a37b46dbb14c15b14c5f473e347869a51f40e1f/torch-2.9.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:524de44cd13931208ba2c4bde9ec7741fd4ae6bfd06409a604fc32f6520c2bc9", size = 899749493, upload-time = "2025-11-12T15:24:36.356Z" }, + { url = "https://files.pythonhosted.org/packages/a6/47/c7843d69d6de8938c1cbb1eba426b1d48ddf375f101473d3e31a5fc52b74/torch-2.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:545844cc16b3f91e08ce3b40e9c2d77012dd33a48d505aed34b7740ed627a1b2", size = 110944162, upload-time = "2025-11-12T15:21:53.151Z" }, + { url = "https://files.pythonhosted.org/packages/28/0e/2a37247957e72c12151b33a01e4df651d9d155dd74d8cfcbfad15a79b44a/torch-2.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5be4bf7496f1e3ffb1dd44b672adb1ac3f081f204c5ca81eba6442f5f634df8e", size = 74830751, upload-time = "2025-11-12T15:21:43.792Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f7/7a18745edcd7b9ca2381aa03353647bca8aace91683c4975f19ac233809d/torch-2.9.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:30a3e170a84894f3652434b56d59a64a2c11366b0ed5776fab33c2439396bf9a", size = 104142929, upload-time = "2025-11-12T15:21:48.319Z" }, + { url = "https://files.pythonhosted.org/packages/f4/dd/f1c0d879f2863ef209e18823a988dc7a1bf40470750e3ebe927efdb9407f/torch-2.9.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2", size = 899748978, upload-time = "2025-11-12T15:23:04.568Z" }, + { url = "https://files.pythonhosted.org/packages/1f/9f/6986b83a53b4d043e36f3f898b798ab51f7f20fdf1a9b01a2720f445043d/torch-2.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db", size = 111176995, upload-time = "2025-11-12T15:22:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/40/60/71c698b466dd01e65d0e9514b5405faae200c52a76901baf6906856f17e4/torch-2.9.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587", size = 74480347, upload-time = "2025-11-12T15:21:57.648Z" }, + { url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245, upload-time = "2025-11-12T15:22:39.027Z" }, + { url = "https://files.pythonhosted.org/packages/81/c9/2628f408f0518b3bae49c95f5af3728b6ab498c8624ab1e03a43dd53d650/torch-2.9.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6", size = 104134804, upload-time = "2025-11-12T15:22:35.222Z" }, + { url = "https://files.pythonhosted.org/packages/28/fc/5bc91d6d831ae41bf6e9e6da6468f25330522e92347c9156eb3f1cb95956/torch-2.9.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9", size = 899747132, upload-time = "2025-11-12T15:23:36.068Z" }, + { url = "https://files.pythonhosted.org/packages/63/5d/e8d4e009e52b6b2cf1684bde2a6be157b96fb873732542fb2a9a99e85a83/torch-2.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d", size = 110934845, upload-time = "2025-11-12T15:22:48.367Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558, upload-time = "2025-11-12T15:22:43.392Z" }, + { url = "https://files.pythonhosted.org/packages/86/5c/5b2e5d84f5b9850cd1e71af07524d8cbb74cba19379800f1f9f7c997fc70/torch-2.9.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7", size = 104145788, upload-time = "2025-11-12T15:23:52.109Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8c/3da60787bcf70add986c4ad485993026ac0ca74f2fc21410bc4eb1bb7695/torch-2.9.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73", size = 899735500, upload-time = "2025-11-12T15:24:08.788Z" }, + { url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659, upload-time = "2025-11-12T15:23:20.009Z" }, ] [[package]] name = "triton" -version = "3.4.0" +version = "3.5.1" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "setuptools", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, -] wheels = [ - { url = "https://files.pythonhosted.org/packages/62/ee/0ee5f64a87eeda19bbad9bc54ae5ca5b98186ed00055281fd40fb4beb10e/triton-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ff2785de9bc02f500e085420273bb5cc9c9bb767584a4aa28d6e360cec70128", size = 155430069, upload-time = "2025-07-30T19:58:21.715Z" }, - { url = "https://files.pythonhosted.org/packages/7d/39/43325b3b651d50187e591eefa22e236b2981afcebaefd4f2fc0ea99df191/triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b70f5e6a41e52e48cfc087436c8a28c17ff98db369447bcaff3b887a3ab4467", size = 155531138, upload-time = "2025-07-30T19:58:29.908Z" }, - { url = "https://files.pythonhosted.org/packages/d0/66/b1eb52839f563623d185f0927eb3530ee4d5ffe9d377cdaf5346b306689e/triton-3.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c1d84a5c0ec2c0f8e8a072d7fd150cab84a9c239eaddc6706c081bfae4eb04", size = 155560068, upload-time = "2025-07-30T19:58:37.081Z" }, - { url = "https://files.pythonhosted.org/packages/30/7b/0a685684ed5322d2af0bddefed7906674f67974aa88b0fae6e82e3b766f6/triton-3.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00be2964616f4c619193cb0d1b29a99bd4b001d7dc333816073f92cf2a8ccdeb", size = 155569223, upload-time = "2025-07-30T19:58:44.017Z" }, - { url = "https://files.pythonhosted.org/packages/20/63/8cb444ad5cdb25d999b7d647abac25af0ee37d292afc009940c05b82dda0/triton-3.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7936b18a3499ed62059414d7df563e6c163c5e16c3773678a3ee3d417865035d", size = 155659780, upload-time = "2025-07-30T19:58:51.171Z" }, + { url = "https://files.pythonhosted.org/packages/fd/6e/676ab5019b4dde8b9b7bab71245102fc02778ef3df48218b298686b9ffd6/triton-3.5.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fc53d849f879911ea13f4a877243afc513187bc7ee92d1f2c0f1ba3169e3c94", size = 170320692, upload-time = "2025-11-11T17:40:46.074Z" }, + { url = "https://files.pythonhosted.org/packages/b0/72/ec90c3519eaf168f22cb1757ad412f3a2add4782ad3a92861c9ad135d886/triton-3.5.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:61413522a48add32302353fdbaaf92daaaab06f6b5e3229940d21b5207f47579", size = 170425802, upload-time = "2025-11-11T17:40:53.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/50/9a8358d3ef58162c0a415d173cfb45b67de60176e1024f71fbc4d24c0b6d/triton-3.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d2c6b915a03888ab931a9fd3e55ba36785e1fe70cbea0b40c6ef93b20fc85232", size = 170470207, upload-time = "2025-11-11T17:41:00.253Z" }, + { url = "https://files.pythonhosted.org/packages/27/46/8c3bbb5b0a19313f50edcaa363b599e5a1a5ac9683ead82b9b80fe497c8d/triton-3.5.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3f4346b6ebbd4fad18773f5ba839114f4826037c9f2f34e0148894cd5dd3dba", size = 170470410, upload-time = "2025-11-11T17:41:06.319Z" }, + { url = "https://files.pythonhosted.org/packages/37/92/e97fcc6b2c27cdb87ce5ee063d77f8f26f19f06916aa680464c8104ef0f6/triton-3.5.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0b4d2c70127fca6a23e247f9348b8adde979d2e7a20391bfbabaac6aebc7e6a8", size = 170579924, upload-time = "2025-11-11T17:41:12.455Z" }, + { url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488, upload-time = "2025-11-11T17:41:18.222Z" }, + { url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" }, ] [[package]] name = "typing-extensions" -version = "4.14.1" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, ] [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, ] [[package]] From e4b21ece9124bf3fe7130b8ee354774c6b5d6463 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 16 Dec 2025 17:54:18 +0100 Subject: [PATCH 089/107] fix: rajout de l'import os dans poweroff --- src/HL/Poweroff.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HL/Poweroff.py b/src/HL/Poweroff.py index 2eac5e7e..7dd033e4 100644 --- a/src/HL/Poweroff.py +++ b/src/HL/Poweroff.py @@ -1,4 +1,5 @@ import subprocess +import os from programme import Program class Poweroff(Program): From b7af974e3b03cf32fd55079f424273594e79d866 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Tue, 16 Dec 2025 17:59:46 +0100 Subject: [PATCH 090/107] fix : suppression de fichier inutile --- To | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 To diff --git a/To b/To deleted file mode 100644 index e69de29b..00000000 From 0d15e34a81db0d1b4c416ae27b9da30d4ca4730d Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 17 Dec 2025 14:05:41 +0100 Subject: [PATCH 091/107] =?UTF-8?q?feat=20:=20changement=20de=20dans=20mod?= =?UTF-8?q?ule=5Finitialisation=20pour=20l'affichage=20(plus=20de=20visibi?= =?UTF-8?q?lit=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/module_initialisation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/HL/module_initialisation.py b/src/HL/module_initialisation.py index e6e22130..a5d3ffec 100644 --- a/src/HL/module_initialisation.py +++ b/src/HL/module_initialisation.py @@ -54,27 +54,27 @@ def init_tof(self,tof): def display(self): text = self.name - text+= "\ncamera: " + text+= "\n camera: " if self.camera_init == 0: text += "(en cour)" elif self.camera_init == 1: - text += "près." + text += "ready." elif self.camera_init == 2: text += "error" - text+= "\nlidar: " + text+= "\n lidar: " if self.lidar_init == 0: text += "(en cour)" elif self.lidar_init == 1: - text += "près." + text += "ready." elif self.lidar_init == 2: text += "error" - text+= "\ntof:" + text+= "\n tof:" if self.tof_init == 0: text += "(en cour)" elif self.tof_init == 1: - text += "près." + text += "ready." elif self.tof_init == 2: text += "error" From d1d32ea5b7e26b33410d83ad2baa3c045bcb99ee Mon Sep 17 00:00:00 2001 From: cbampeta Date: Wed, 17 Dec 2025 17:05:23 +0100 Subject: [PATCH 092/107] fix: soucis oublie de self dans poweroff --- src/HL/Poweroff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HL/Poweroff.py b/src/HL/Poweroff.py index 7dd033e4..5c430b1a 100644 --- a/src/HL/Poweroff.py +++ b/src/HL/Poweroff.py @@ -9,10 +9,10 @@ def __init__(self): self.controls_car = False self.running = False - def kill(): + def kill(self): pass - def start(): + def start(self): subprocess.Popen( "sudo poweroff", shell=True, From 0525d89dccc69f1aac83dc8f88b6ab4902ab6fd7 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 14:02:29 +0100 Subject: [PATCH 093/107] =?UTF-8?q?fix:=20revue=20de=20la=20structure=20du?= =?UTF-8?q?=20code=20(en=20terme=20de=20architecture=20des=20fichier=20ave?= =?UTF-8?q?c=20creation=20de=20dossier=20et=20d=C3=A9placement=20des=20fic?= =?UTF-8?q?hiers=20pour=20plus=20de=20lisibilit=C3=A9=20du=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur.py | 103 ----------- src/HL/Serveur_mq.py | 20 +- src/HL/{ => actionneur_capteur}/Camera.py | 4 +- src/HL/{ => actionneur_capteur}/Lidar.py | 0 src/HL/{ => actionneur_capteur}/ToF.py | 0 src/HL/main.py | 172 ------------------ src/HL/{ => programme}/Camera_serv.py | 0 src/HL/{ => programme}/Car.py | 7 +- src/HL/{ => programme}/Driver.py | 2 +- src/HL/{ => programme}/Poweroff.py | 0 src/HL/{ => programme}/RemoteControl.py | 0 src/HL/{ => programme}/SshProgramme.py | 0 src/HL/{ => programme}/get_ip.py | 0 .../{ => programme}/module_initialisation.py | 2 +- src/HL/{ => programme}/programme.py | 2 +- 15 files changed, 17 insertions(+), 295 deletions(-) delete mode 100644 src/HL/Serveur.py rename src/HL/{ => actionneur_capteur}/Camera.py (98%) rename src/HL/{ => actionneur_capteur}/Lidar.py (100%) rename src/HL/{ => actionneur_capteur}/ToF.py (100%) delete mode 100644 src/HL/main.py rename src/HL/{ => programme}/Camera_serv.py (100%) rename src/HL/{ => programme}/Car.py (96%) rename src/HL/{ => programme}/Driver.py (98%) rename src/HL/{ => programme}/Poweroff.py (100%) rename src/HL/{ => programme}/RemoteControl.py (100%) rename src/HL/{ => programme}/SshProgramme.py (100%) rename src/HL/{ => programme}/get_ip.py (100%) rename src/HL/{ => programme}/module_initialisation.py (98%) rename src/HL/{ => programme}/programme.py (92%) diff --git a/src/HL/Serveur.py b/src/HL/Serveur.py deleted file mode 100644 index c37614fe..00000000 --- a/src/HL/Serveur.py +++ /dev/null @@ -1,103 +0,0 @@ -import time -import sys -# from systemd.journal import JournalHandler #il y a des soucis dessus pour linstant -import zerorpc -import struct -import logging as log - -# from Camera import Camera -import smbus #type: ignore - -# uv pip install systemd-python -# uv pip install picamera2 -# sudo apt install python3-libcamera -""" -Lancer un serveur qui tourne h24 qui gere l'intercommunication des processus (qui sont externe a la Pi) -Cf envoie vitesse a l'arduino, communication avec l'ecran , avec les boutons ,avec le lidar et la camera -Tout doit passer par cette classe qui tourne s -""" - -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 - -# I2C address of the slave -SLAVE_ADDRESS = 0x08 - - -class ApiVoiture(): # pylint: disable=too-few-public-methods - """ - ça controlera tout - """ - - def __init__(self): - self.vitesse_r = 0 # vitesse en metre par seconde réel - self.vitesse_d = 0 # vitesse demander en metre par seconde - self.direction = 0 # direction en degrés avec 0 le degré du centre - self.voltage_lipo = 0 - self.voltage_nimh = 0 - log.basicConfig(level=log.INFO) # Mettre log.DEBUG pour plus de détails - log.info("Initialisation de la caméra...") - # self.cam = Camera() - log.info("Caméra initialisée.") - log.info("Démarrage du thread de capture...") - # self.cam.start() - log.info("Thread de capture démarré.") - self.vitesse_m_s = 0 - self.direction = 0 - - def write_vitesse_direction(self,vitesse, direction): - - self.vitesse_d = vitesse #on enregistre la vitesse demandé - self.direction = direction # on enregistre la direction voulue - - data = struct.pack('= length: - float_values = struct.unpack('f' * num_floats, bytes(data[:length])) - list_valeur = list(float_values) - - # on enregistre les valeur - self.voltage_lipo = list_valeur[0] - self.voltage_nimh = list_valeur[1] - self.vitesse_r = list_valeur[2] - - return list_valeur - else: - raise ValueError("Not enough data received from I2C bus") - - - def gen_frames(self): - """Générateur qui lit le flux depuis l'objet Caméra.""" - log.info("Démarrage du flux vidéo.") - while True: - # Limite le framerate pour ne pas saturer le réseau - time.sleep(0.05) # ~20 images/seconde - - frame_bytes = None - - # Lit l'image la plus récente de manière thread-safe - with self.cam.streaming_lock: - frame_bytes = self.cam.streaming_frame - - if frame_bytes: - # Envoie l'image au navigateur - yield (b'--frame\r\n' - b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n') - -if __name__ == '__main__': - - try: - api = ApiVoiture() - s = zerorpc.Server(api) - s.bind("tcp://0.0.0.0:4242") - print("Serveur ZERORPC lancé sur tcp://0.0.0.0:4242") - s.run() - except Exception as e: - print("Erreur au démarrage :", e) \ No newline at end of file diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 1d9e003d..5cc32954 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -18,21 +18,21 @@ import textwrap import socket -from get_ip import get_ip, check_ssh_connections +from src.HL.programme.get_ip import check_ssh_connections import subprocess -from Lidar import Lidar -from Camera import Camera -from ToF import ToF +from src.HL.actionneur_capteur.Lidar import Lidar +from src.HL.actionneur_capteur.Camera import Camera +from src.HL.actionneur_capteur.ToF import ToF from Autotech_constant import SOCKET_ADRESS, SLAVE_ADDRESS #différent programme from scripts.commande_PS4 import PS4ControllerProgram -from SshProgramme import SshProgramme -from RemoteControl import RemoteControl -from Poweroff import Poweroff -from Camera import ProgramStreamCamera -from module_initialisation import Initialisation -from Car import Ai_Programme +from src.HL.programme.SshProgramme import SshProgramme +from src.HL.programme.RemoteControl import RemoteControl +from src.HL.programme.Poweroff import Poweroff +from src.HL.actionneur_capteur.Camera import ProgramStreamCamera +from src.HL.programme.module_initialisation import Initialisation +from src.HL.programme.Car import Ai_Programme serial = i2c(port=1, address=0x3C) device = ssd1306(serial) diff --git a/src/HL/Camera.py b/src/HL/actionneur_capteur/Camera.py similarity index 98% rename from src/HL/Camera.py rename to src/HL/actionneur_capteur/Camera.py index f063ce3a..2df33b59 100644 --- a/src/HL/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -38,8 +38,8 @@ def outputframe(self, frame, keyframe=True): -from Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer -from programme import Program +from ..programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer +from ..programme.programme import Program class ProgramStreamCamera(Program): def __init__(self,serveur): diff --git a/src/HL/Lidar.py b/src/HL/actionneur_capteur/Lidar.py similarity index 100% rename from src/HL/Lidar.py rename to src/HL/actionneur_capteur/Lidar.py diff --git a/src/HL/ToF.py b/src/HL/actionneur_capteur/ToF.py similarity index 100% rename from src/HL/ToF.py rename to src/HL/actionneur_capteur/ToF.py diff --git a/src/HL/main.py b/src/HL/main.py deleted file mode 100644 index ee96d09f..00000000 --- a/src/HL/main.py +++ /dev/null @@ -1,172 +0,0 @@ -# States -# 0 - Idle -# 1 - Auto Driving -# 2 - Manual Driving with ps4 controller - -from gpiozero import LED, Button, Buzzer -from luma.core.interface.serial import i2c -from luma.core.render import canvas -from luma.oled.device import ssd1306 -from PIL import Image, ImageDraw, ImageFont -import struct -import smbus # type: ignore #ignore the module could not be resolved error because it is a linux only module -import textwrap - -from get_ip import get_ip, check_ssh_connections - -from multiprocessing import Processus #pour pouvoir lancer les programme sur un cpu différent - -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 -#oled -serial = i2c(port=1, address=0x3C) -device = ssd1306(serial) - -auto_driving_p = Process(target=Auto_Driving) -manual_driving_p = Process(target=Manual_Driving) - -list_p = [auto_driving_p,manual_driving_p] #liste tout les processus possible - -SLAVE_ADDRESS = 0x08 # I2C address of the slave arduino or stm32 -bp_next = Button("GPIO5", bounce_time=0.1) -bp_entre = Button("GPIO6", bounce_time=0.1) -led1 = LED("GPIO17") -led2 = LED("GPIO27") -buzzer = Buzzer("GPIO26") -State = 0 -Screen = 0 -TEXT_HEIGHT = 11 -TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff - - -def make_voltage_im(): - try: #Will fail if arduino is rest ex: temporary power loss when plugu=ing in usb - received = read_data(2) # Adjust length as needed - except OSError: - received = [0.0, 0.0] - print("I2C bus error") - - # filter out values below 6V and round to 2 decimal places - received = [round(elem, 2) if elem > 6 else 0.0 for elem in received] - text = f"LiP:{received[0]:.2f}V|NiH:{received[1]:.2f}V" - im = Image.new("1", (128, TEXT_HEIGHT), "black") - draw = ImageDraw.Draw(im) - font = ImageFont.load_default() - draw.text((3, 0), text, fill="white", font=font) - return im - -def display_combined_im(text): - im = Image.new("1", (128, 64), "black") - draw = ImageDraw.Draw(im) - font = ImageFont.load_default() - - # Wrap the text to fit within the width of the display - wrapped_text = textwrap.fill(text, width=20) # Adjust width as needed - draw.text((3, 0), wrapped_text, fill="white", font=font) - - voltage_im = make_voltage_im() - im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) - - with canvas(device) as draw: - draw.bitmap((0, 0), im, fill="white") - -def write_data(float_data): - # Convert the float to bytes - print(float_data) - byte_data = struct.pack('f', float_data) - # Convert the bytes to a list of integers - int_data = list(byte_data) - print(int_data) - int_data.append(0) - # Write the data to the I2C bus - bus.write_i2c_block_data(SLAVE_ADDRESS, int_data[0], int_data[1:4]) - -def read_data(num_floats=3): - - # Each float is 4 bytes - length = num_floats * 4 - # Read a block of data from the slave - data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length) - # Convert the byte data to floats - if len(data) >= length: - float_values = struct.unpack('f' * num_floats, bytes(data[:length])) - return list(float_values) - else: - raise ValueError("Not enough data received from I2C bus") - - -def Idle(): #Enable chossing between states - global Screen - global State - if Screen==0 and check_ssh_connections(): - led1.on() - Screen=1 - if not check_ssh_connections(): - led1.off() - match Screen: #Display on OLED - case 0: #IP and ssh status - ip=get_ip() - text = "Ready to SSH\nIP:"+ip - case 1: #AutoDriving mode - text = "Auto Driving" - case 2: #Manual Driving mode - text = "Manual Driving With PS4 Controller" - #PS4 controller status - case 3: #Kill all processus - text = "Kill all the process" - - if (State==Screen): - text+=": (en cours)" - - display_combined_im(text) - - - if bp_next.is_pressed: - bp_next.wait_for_release() - Screen+=1 - if Screen>len(list_p): - Screen=0 - if bp_entre.is_pressed: - bp_entre.wait_for_release() - State=Screen - p_choisie(State-1) # -1 because of the process cases begin at 1 and the list_p indexe at 0 - -def p_choisie(p_id): - """ Kill tout les processus et lance celui choisie par p_id dans la liste list_p - (Donner un p_id plus grand que len(list_p) tue tout les processus - """ - for i in range(len(list_p)): - if (i!= p_id): - list_p[i].terminate() - - if (p_id Date: Fri, 19 Dec 2025 14:16:51 +0100 Subject: [PATCH 094/107] =?UTF-8?q?fix:=20resolution=20de=20chemin=20de=20?= =?UTF-8?q?dependance=20pour=20les=20import=20(et=20aussi=20quelque=20supe?= =?UTF-8?q?r=20init=20qui=20manqu=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/commande_PS4.py | 2 +- src/HL/actionneur_capteur/Camera.py | 4 ++-- src/HL/programme/Camera_serv.py | 2 +- src/HL/programme/Car.py | 2 +- src/HL/programme/Poweroff.py | 2 +- src/HL/programme/RemoteControl.py | 2 +- src/HL/programme/SshProgramme.py | 3 ++- src/HL/programme/module_initialisation.py | 3 ++- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 0342d9a0..f084dfe8 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -2,7 +2,7 @@ import time import os from threading import Thread -from programme import Program +from src.HL.programme.programme import Program from src.HL.Autotech_constant import MAX_ANGLE ################################################### #Intialisation du protocole zmq diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index 2df33b59..84d02cab 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -38,8 +38,8 @@ def outputframe(self, frame, keyframe=True): -from ..programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer -from ..programme.programme import Program +from src.HL.programme.programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer +from src.HL.programme.programme import Program class ProgramStreamCamera(Program): def __init__(self,serveur): diff --git a/src/HL/programme/Camera_serv.py b/src/HL/programme/Camera_serv.py index 505cb2f8..a2c04597 100644 --- a/src/HL/programme/Camera_serv.py +++ b/src/HL/programme/Camera_serv.py @@ -6,7 +6,7 @@ from threading import Condition streaming_enabled = True -from Camera_serv import streaming_enabled +from src.HL.programme.Camera_serv import streaming_enabled class FrameBuffer: def __init__(self): diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 823e1bc4..33132858 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -7,7 +7,7 @@ import smbus # type: ignore #ignore the module could not be resolved error because it is a linux only module import struct from threading import Thread -from programme import Program +from src.HL.programme.programme import Program # Import constants from HL.Autotech_constant to share them between files and ease of use from ..Autotech_constant import MAX_SOFT_SPEED, MAX_ANGLE, CRASH_DIST, MODEL_PATH, SOCKET_ADRESS, REAR_BACKUP_DIST, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET diff --git a/src/HL/programme/Poweroff.py b/src/HL/programme/Poweroff.py index 5c430b1a..13138029 100644 --- a/src/HL/programme/Poweroff.py +++ b/src/HL/programme/Poweroff.py @@ -1,6 +1,6 @@ import subprocess import os -from programme import Program +from src.HL.programme.programme import Program class Poweroff(Program): def __init__(self): diff --git a/src/HL/programme/RemoteControl.py b/src/HL/programme/RemoteControl.py index 91e2c628..57145398 100644 --- a/src/HL/programme/RemoteControl.py +++ b/src/HL/programme/RemoteControl.py @@ -1,4 +1,4 @@ -from programme import Program +from src.HL.programme.programme import Program import struct import socket import threading diff --git a/src/HL/programme/SshProgramme.py b/src/HL/programme/SshProgramme.py index dc43ec81..aafa1fc2 100644 --- a/src/HL/programme/SshProgramme.py +++ b/src/HL/programme/SshProgramme.py @@ -1,9 +1,10 @@ -from programme import Program +from src.HL.programme.programme import Program from get_ip import get_ip, check_ssh_connections import logging as log class SshProgramme(Program): """montre le menu ssh de la voiture et si séléctionner comme programme force la vitesse et la direction à 0""" def __init__(self): + super().__init__() self.name = "Ssh to:" + get_ip() self.running = True self.controls_car = True diff --git a/src/HL/programme/module_initialisation.py b/src/HL/programme/module_initialisation.py index e73a9ad2..b220a91a 100644 --- a/src/HL/programme/module_initialisation.py +++ b/src/HL/programme/module_initialisation.py @@ -1,10 +1,11 @@ -from programme import Program +from src.HL.programme.programme import Program import threading from ..Autotech_constant import SOCKET_ADRESS import logging as log class Initialisation(Program): def __init__(self, camera, lidar, tof): + super().__init__() self.name = "Initialisation:" self.camera = None self.lidar = None From 1efb726d458f7994d3c965531b46b448e5fc0aca Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 14:22:14 +0100 Subject: [PATCH 095/107] fix: toujours changement relatif au import --- src/HL/actionneur_capteur/Camera.py | 2 +- src/HL/programme/Car.py | 2 +- src/HL/programme/SshProgramme.py | 2 +- src/HL/programme/{ => scripts}/Driver.py | 0 src/HL/programme/{ => scripts}/get_ip.py | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename src/HL/programme/{ => scripts}/Driver.py (100%) rename src/HL/programme/{ => scripts}/get_ip.py (100%) diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index 84d02cab..b9f9cb45 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -38,7 +38,7 @@ def outputframe(self, frame, keyframe=True): -from src.HL.programme.programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer +from src.HL.programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer from src.HL.programme.programme import Program class ProgramStreamCamera(Program): diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 33132858..2e114577 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -11,7 +11,7 @@ # Import constants from HL.Autotech_constant to share them between files and ease of use from ..Autotech_constant import MAX_SOFT_SPEED, MAX_ANGLE, CRASH_DIST, MODEL_PATH, SOCKET_ADRESS, REAR_BACKUP_DIST, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET -from Driver import Driver +from src.HL.programme.scripts.Driver import Driver class Car: diff --git a/src/HL/programme/SshProgramme.py b/src/HL/programme/SshProgramme.py index aafa1fc2..904f24e6 100644 --- a/src/HL/programme/SshProgramme.py +++ b/src/HL/programme/SshProgramme.py @@ -1,5 +1,5 @@ from src.HL.programme.programme import Program -from get_ip import get_ip, check_ssh_connections +from src.HL.programme.scripts.get_ip import get_ip, check_ssh_connections import logging as log class SshProgramme(Program): """montre le menu ssh de la voiture et si séléctionner comme programme force la vitesse et la direction à 0""" diff --git a/src/HL/programme/Driver.py b/src/HL/programme/scripts/Driver.py similarity index 100% rename from src/HL/programme/Driver.py rename to src/HL/programme/scripts/Driver.py diff --git a/src/HL/programme/get_ip.py b/src/HL/programme/scripts/get_ip.py similarity index 100% rename from src/HL/programme/get_ip.py rename to src/HL/programme/scripts/get_ip.py From d61c7228291a36f748f32f23296e696a0aa172a8 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 18:49:45 +0100 Subject: [PATCH 096/107] fix: toujours changement relatif au import --- src/HL/Serveur_mq.py | 2 +- src/HL/programme/scripts/Driver.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 5cc32954..939e886e 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -18,7 +18,7 @@ import textwrap import socket -from src.HL.programme.get_ip import check_ssh_connections +from src.HL.programme.scripts.get_ip import check_ssh_connections import subprocess from src.HL.actionneur_capteur.Lidar import Lidar from src.HL.actionneur_capteur.Camera import Camera diff --git a/src/HL/programme/scripts/Driver.py b/src/HL/programme/scripts/Driver.py index 8cb4071e..394834c0 100644 --- a/src/HL/programme/scripts/Driver.py +++ b/src/HL/programme/scripts/Driver.py @@ -6,7 +6,7 @@ import onnxruntime as ort import logging as log -from ..Autotech_constant import SPEED_LOOKUP, ANGLE_LOOKUP, MODEL_PATH, Temperature +from src.HL.Autotech_constant import SPEED_LOOKUP, ANGLE_LOOKUP, MODEL_PATH, Temperature From 752b6774371bab16ca690257eab4ea2a9a059fec Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 21:37:41 +0100 Subject: [PATCH 097/107] feat: rajout de log partout --- scripts/commande_PS4.py | 3 + src/HL/Serveur_mq.py | 76 +++++++++++++++++++---- src/HL/actionneur_capteur/Camera.py | 6 +- src/HL/actionneur_capteur/Lidar.py | 17 ++--- src/HL/actionneur_capteur/ToF.py | 4 +- src/HL/programme/Camera_serv.py | 5 +- src/HL/programme/Car.py | 31 ++++----- src/HL/programme/Poweroff.py | 2 + src/HL/programme/RemoteControl.py | 3 + src/HL/programme/SshProgramme.py | 4 +- src/HL/programme/module_initialisation.py | 21 +++---- src/HL/programme/programme.py | 12 ++-- src/HL/programme/scripts/Driver.py | 15 ++--- 13 files changed, 132 insertions(+), 67 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index f084dfe8..5ae3a14c 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -4,6 +4,7 @@ from threading import Thread from src.HL.programme.programme import Program from src.HL.Autotech_constant import MAX_ANGLE +import logging ################################################### #Intialisation du protocole zmq ################################################## @@ -40,6 +41,7 @@ class PS4ControllerProgram(Program): def __init__(self): super().__init__() + self.log = logging.getLogger(__name__) self.name = "PS4 Controller" self.running = False self.controls_car = True @@ -74,6 +76,7 @@ class MyController(Controller): def __init__(self, **kwargs): super().__init__(**kwargs) + self.log = logging.getLogger(__name__) self.vitesse_mms = 0 # vitesse initiale en métre par milliseconde self.direction_d = 0 # angle initiale des roues en degrés self.filtered = 0 diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 939e886e..d5de1059 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -5,7 +5,7 @@ import time import threading import smbus -import logging as log +import logging import struct import os, signal @@ -34,12 +34,7 @@ from src.HL.programme.module_initialisation import Initialisation from src.HL.programme.Car import Ai_Programme -serial = i2c(port=1, address=0x3C) -device = ssd1306(serial) -#on démarre les log -log.basicConfig(level=log.INFO) -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 #le nombre de donnée récupéré par l'i2c @@ -59,16 +54,27 @@ class Serveur(): def __init__(self): + self.log = logging.getLogger(__name__) #initialisation des différents module qui tourne tout le temps + self.log.info("Initialisation du serveur") + self.bp_next = Button("GPIO5", bounce_time=0.1) self.bp_entre = Button("GPIO6", bounce_time=0.1) self.led1 = LED("GPIO17") self.led2 = LED("GPIO27") self.buzzer = Buzzer("GPIO26") + self.log.info("GPIO: boutons, LEDs, buzzer initialisés") + self.remote_control = False # on initialise le remote control à False + + self.serial = i2c(port=1, address=0x3C) + self.device = ssd1306(self.serial) + self.bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 + self.log.info("I2C: bus ouvert sur /dev/i2c-1") + self.length_i2c_received = 3 #nombre de donnée à récupéré de l'arduino (voltage lipo, voltage nimh) # initialisation des donnnée de la voiture @@ -97,6 +103,7 @@ def __init__(self): self.programme = [SshProgramme(), self.initialisation_module, Ai_Programme(self), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self), Poweroff()] + self.log.debug("Programmes chargés: %s", [p.name for p in self.programme]) # donnée de l'écran self.Screen = 0 @@ -132,7 +139,7 @@ def affichage_oled(self,selected): #test non utilisé else: draw.text((3, y), self.programme[i]["name"], fill="white", font=font) - with canvas(device) as display: + with canvas(self.device) as display: display.bitmap((0, 0), im, fill="white") def make_voltage_im(self): @@ -161,7 +168,7 @@ def display_combined_im(self,text): voltage_im = self.make_voltage_im() im.paste(voltage_im, (0, 64 - TEXT_HEIGHT)) - with canvas(device) as draw: + with canvas(self.device) as draw: draw.bitmap((0, 0), im, fill="white") @@ -200,20 +207,21 @@ def bouton_entre(self,num=None): #--------------------------------------------------------------------------------------------------- def i2c_loop(self): """Envoie vitesse/direction régulièrement au microcontroleur. (toute les frames actuellement)""" - print("lancement de l'i2c") + self.log.info("Thread I2C loop démarré") while True: try : data = struct.pack('= length: float_values = struct.unpack('f' * self.length_i2c_received, bytes(data[:length])) @@ -223,6 +231,8 @@ def i2c_received(self): self.voltage_lipo = list_valeur[0] self.voltage_nimh = list_valeur[1] self.vitesse_r = list_valeur[2] + else: + self.log.warning("I2C: taille inattendue (%d au lieu de %d)", len(data), length) time.sleep(0.1) def envoie_donnee(self, socket): @@ -262,15 +272,33 @@ def start_process(self,num_programme): """lance le porgramme référencé avec son numéro: si il sagit d'un programme qui controle la voiture il kill lancient programme qui controlé, sinon le programme est lancé ou tué celon si il était déjà lancé ou tué avant""" + self.log.info("Action utilisateur: programme %d (%s)", + num_programme, + self.programme[num_programme].name) if self.programme[num_programme].running: self.programme[num_programme].kill() if self.programme[num_programme].controls_car: self.last_programme_control = 0 + self.log.warning( + "Changement de contrôle voiture: %s -> %s", + type(self.programme[num_programme]).__name__, + type(self.programme[self.last_programme_control]).__name__ + ) + + + self.log.info("Arrêt du programme %s", + self.programme[num_programme].name) elif self.programme[num_programme].controls_car: self.programme[self.last_programme_control].kill() self.programme[num_programme].start() + self.log.warning( + "Changement de contrôle voiture: %s -> %s", + type(self.programme[self.last_programme_control]).__name__, + type(self.programme[num_programme]).__name__ + ) self.last_programme_control = num_programme + else: self.programme[num_programme].start() @@ -293,7 +321,9 @@ def main(self): threading.Thread(target=self.i2c_loop, daemon=True).start() threading.Thread(target=self.i2c_received, daemon=True).start() threading.Thread(target=self.envoie_donnee, args=(telemetry,), daemon=True).start() - + + self.log.info("Serveur démarré, entrée dans la boucle principale") + while True: self.Idle() @@ -302,5 +332,25 @@ def main(self): #--------------------------------------------------------------------------------------------------- if __name__ == "__main__": + + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s | %(levelname)s | %(name)s | %(message)s", + handlers=[ + logging.FileHandler("/home/intech/CoVAPSy/covapsy.log"), + logging.StreamHandler() + ] + + ) + log_serveur = logging.getLogger("__main__") + log_serveur.setLevel(level=logging.DEBUG) + + log_serveur = logging.getLogger("src.HL") + log_serveur.setLevel(level=logging.DEBUG) + + log_lidar = logging.getLogger("src.HL.actionneur_capteur.Lidar") + log_lidar.setLevel(level=logging.INFO) + + boot = Serveur() boot.main() diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index b9f9cb45..fe1fcb8e 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -44,6 +44,7 @@ def outputframe(self, frame, keyframe=True): class ProgramStreamCamera(Program): def __init__(self,serveur): super().__init__() + self.log = logging.getLogger(__name__) self.name = "Streaming Video" self.serveur = serveur self.running = False @@ -58,8 +59,9 @@ def camera(self): def start(self): cam = self.camera if cam is None: - print("Camera not initialized yet") + self.log.error("Camera not initialized yet") return + self.running = True self.camera.start_stream() @@ -94,7 +96,7 @@ def __init__(self, size=(1280, 720), port=8000): def _start_local_capture(self): self.picam2 = Picamera2() config = self.picam2.create_video_configuration( - main={"size": (1280, 720)}, # plus large, moins zoomé + main={"size": self.size}, # plus large, moins zoomé controls={"FrameRate": 30} # FPS stable ) diff --git a/src/HL/actionneur_capteur/Lidar.py b/src/HL/actionneur_capteur/Lidar.py index f3461400..42195572 100644 --- a/src/HL/actionneur_capteur/Lidar.py +++ b/src/HL/actionneur_capteur/Lidar.py @@ -27,7 +27,7 @@ import _thread as thread import numpy as np import matplotlib.pyplot as plt -import logging as log +import logging class Lidar(): measureMsgHeads = {'ME', 'GE', 'MD', 'GD'} @@ -66,6 +66,7 @@ def partition(n: int, lst): return ns def __init__(self, ip, port, startStep=0): + self.log = logging.getLogger(__name__) self.ip = ip self.port = port # For decoding measuring data @@ -109,9 +110,9 @@ def toCartesian(xTheta, xR): # axp.set_thetamax(deg2theta(45)) # axp.set_thetamax(deg2theta(270 + 45)) axp.grid(True) - log.info('Plotter started, press any key to exit') + self.log.info('Plotter started, press any key to exit') - log.debug(f'{self.xTheta}, {self.rDistance}') + self.log.debug(f'{self.xTheta}, {self.rDistance}') while True: X, Y = toCartesian(self.xTheta, self.rDistance) @@ -143,14 +144,14 @@ def formatZeros(addr): gateway = formatZeros(gateway) netmask = formatZeros(netmask) cmd = f'$IP{ip}{netmask}{gateway}\r\n' - log.debug(f'ChangeIP cmd: {cmd}') + self.log.debug(f'ChangeIP cmd: {cmd}') self.send(cmd) # Start continous read mode def startContinuous(self, start: int, end: int, withIntensity=False): head = 'ME' if withIntensity else 'MD' cmd = f'{head}{start:04d}{end:04d}00000\r\n' - log.debug(cmd) + self.log.debug(cmd) self.head = cmd.strip() self.send(cmd) @@ -184,7 +185,7 @@ def handleMsgLine(self, line): return True else: self.buf += line.strip() - # log.debug(f'buf size {len(self.buf)}') + # self.log.debug(f'buf size {len(self.buf)}') if len(self.buf) >= self.expectedPacketSize: self.decodeDistance(self.buf) self.buf = '' @@ -197,7 +198,7 @@ def handleMeasuring(msg): lines = msg.split() for line in lines: if not self.handleMsgLine(line): - log.debug(f'ignore {line}') + self.log.debug(f'ignore {line}') def loop(): try: @@ -207,7 +208,7 @@ def loop(): msg = m.decode() handleMeasuring(msg) except socket.timeout as e: - log.error('Read timeout, sensor disconnected?') + self.log.error('Read timeout, sensor disconnected?') os._exit(1) finally: self.sock.close() diff --git a/src/HL/actionneur_capteur/ToF.py b/src/HL/actionneur_capteur/ToF.py index 9a9c1a96..2fc75b5e 100644 --- a/src/HL/actionneur_capteur/ToF.py +++ b/src/HL/actionneur_capteur/ToF.py @@ -10,7 +10,7 @@ class ToF: """ def __init__(self): - + self.log = logging.getLogger(__name__) i2c = busio.I2C(board.SCL, board.SDA) self.vl53 = VL53L0X(i2c) @@ -22,6 +22,6 @@ def get_distance(self): distance = self.vl53.range return distance except Exception as e: - logging.error(f"Error reading rear ToF sensor: {e}") + self.log.error(f"Error reading rear ToF sensor: {e}") return None diff --git a/src/HL/programme/Camera_serv.py b/src/HL/programme/Camera_serv.py index a2c04597..b3f3f4b5 100644 --- a/src/HL/programme/Camera_serv.py +++ b/src/HL/programme/Camera_serv.py @@ -34,6 +34,9 @@ def write(self, buf): class StreamHandler(server.BaseHTTPRequestHandler): + def __init__(self): + self.log = logging.getLogger(__name__) + def do_GET(self): if self.path != "/stream.mjpg": self.send_error(404) @@ -63,7 +66,7 @@ def do_GET(self): self.wfile.write(b"\r\n") except Exception as e: - logging.warning("Client disconnected: %s", e) + self.log.warning("Client disconnected: %s", e) class StreamServer(socketserver.ThreadingMixIn, server.HTTPServer): diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 2e114577..3af02ca7 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -3,7 +3,7 @@ from scipy.special import softmax import numpy as np from gpiozero import LED, Button -import logging as log +import logging import smbus # type: ignore #ignore the module could not be resolved error because it is a linux only module import struct from threading import Thread @@ -16,6 +16,8 @@ class Car: def __init__(self,driving_strategy, serveur): + self.log = logging.getLogger(__name__) + """Initialize the car's components.""" self.vitesse_d = 0 # Speed in millimeters per second self.direction_d = 0 # Steering angle in degrees @@ -25,16 +27,16 @@ def _initialize_ai(): """Initialize the AI session.""" try: self.ai_session = ort.InferenceSession(MODEL_PATH) - log.info("AI session initialized successfully") + self.log.info("AI session initialized successfully") except Exception as e: - log.error(f"Error initializing AI session: {e}") + self.log.error(f"Error initializing AI session: {e}") raise # Initialize AI session _initialize_ai() self.driving = driving_strategy - log.info("Car initialization complete") + self.log.info("Car initialization complete") # accès dynamique aux capteurs @property def camera(self): @@ -58,7 +60,7 @@ def stop(self): def has_Crashed(self): small_distances = [d for d in self.lidar.rDistance[200:880] if 0 < d < CRASH_DIST] # 360 to 720 is the front of the car. 1/3 of the fov of the lidar - log.debug(f"Distances: {small_distances}") + self.log.debug(f"Distances: {small_distances}") if len(small_distances) > 2: # min_index = self.lidar.rDistance.index(min(small_distances)) while self.tof.get_distance() < REAR_BACKUP_DIST: @@ -70,7 +72,7 @@ def has_Crashed(self): def turn_around(self): """Turn the car around.""" - log.info("Turning around") + self.log.info("Turning around") self.vitesse_d = 0 self.direction_d = MAX_ANGLE @@ -84,7 +86,7 @@ def turn_around(self): def main(self): # récupération des données du lidar. On ne prend que les 1080 premières valeurs et on ignore la dernière par facilit" pour l'ia if self.camera is None or self.lidar is None or self.tof is None: - log.debug("Capteurs pas encore prêts") + self.log.debug("Capteurs pas encore prêts") print("Capteurs pas encore prêts") return lidar_data = (self.lidar.rDistance[:1080]/1000) @@ -92,7 +94,7 @@ def main(self): LIDAR_DATA_OFFSET + LIDAR_DATA_AMPLITUDE * np.exp(-1/2*((np.arange(1080) - 135) / LIDAR_DATA_SIGMA**2)) ) #convertir en mètre et ajouter un bruit gaussien #On traffique les données fournit a l'IA self.direction_d, self.vitesse_d = self.driving(lidar_data_ai) #l'ai prend des distance en mètre et non en mm - log.debug(f"Min Lidar: {min(lidar_data)}, Max Lidar: {max(lidar_data)}") + self.log.debug(f"Min Lidar: {min(lidar_data)}, Max Lidar: {max(lidar_data)}") if self.camera.is_running_in_reversed(): self.reverse_count += 1 @@ -107,16 +109,16 @@ def main(self): if color == 0: small_distances = [d for d in self.lidar.rDistance if 0 < d < CRASH_DIST] if len(small_distances) == 0: - log.info("Aucun obstacle détecté") + self.log.info("Aucun obstacle détecté") return min_index = np.argmin(small_distances) direction = MAX_ANGLE if min_index < 540 else -MAX_ANGLE #540 is the middle of the lidar color = direction/direction - log.info("Obstacle détecté, Lidar Fallback") + self.log.info("Obstacle détecté, Lidar Fallback") if color == -1: - log.info("Obstacle rouge détecté") + self.log.info("Obstacle rouge détecté") if color == 1: - log.info("Obstacle vert détecté") + self.log.info("Obstacle vert détecté") angle= -color*MAX_ANGLE self.vitesse_d = -2 self.direction_d = angle @@ -127,6 +129,7 @@ def main(self): class Ai_Programme(Program): def __init__(self, serveur): super().__init__() + self.log = logging.getLogger(__name__) self.name = "IA autonome" self.serveur = serveur @@ -152,7 +155,7 @@ def run(self): try: self.GR86.main() except Exception as e: - log.error(f"Erreur IA: {e}") + self.log.error(f"Erreur IA: {e}") self.running = False def start(self): @@ -168,7 +171,7 @@ def start(self): self.driver.load_model() self.GR86 = Car(self.driver, self.serveur) except Exception as e: - log.error(f"Impossible de démarrer l'IA: {e}") + self.log.error(f"Impossible de démarrer l'IA: {e}") self.driver = None self.GR86 = None return diff --git a/src/HL/programme/Poweroff.py b/src/HL/programme/Poweroff.py index 13138029..17b3fe5b 100644 --- a/src/HL/programme/Poweroff.py +++ b/src/HL/programme/Poweroff.py @@ -5,6 +5,7 @@ class Poweroff(Program): def __init__(self): super().__init__() + self.log = logging.getLogger(__name__) self.name = "Power off" self.controls_car = False self.running = False @@ -13,6 +14,7 @@ def kill(self): pass def start(self): + self.log("Power off started") subprocess.Popen( "sudo poweroff", shell=True, diff --git a/src/HL/programme/RemoteControl.py b/src/HL/programme/RemoteControl.py index 57145398..8c201a93 100644 --- a/src/HL/programme/RemoteControl.py +++ b/src/HL/programme/RemoteControl.py @@ -8,6 +8,7 @@ class RemoteControl(Program): """ ce programme permet de prendre le control de la voiture à distance en utilsant des packet udp""" def __init__(self): super().__init__() + self.log = logging.getLogger(__name__) self.name = "Remote Control" self.controls_car = True self.running = False @@ -18,6 +19,8 @@ def __init__(self): self.public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.public.bind(("0.0.0.0", 5556)) + self.log.info("Initialisation de Remote control fini") + def car_controle(self,sock): """ on regarde si il s'agit de lappelle pour le control interne (is_private) ou si on veux prendre le controle depuis le pc.""" diff --git a/src/HL/programme/SshProgramme.py b/src/HL/programme/SshProgramme.py index 904f24e6..14d95e4f 100644 --- a/src/HL/programme/SshProgramme.py +++ b/src/HL/programme/SshProgramme.py @@ -5,7 +5,7 @@ class SshProgramme(Program): """montre le menu ssh de la voiture et si séléctionner comme programme force la vitesse et la direction à 0""" def __init__(self): super().__init__() - self.name = "Ssh to:" + get_ip() + self.ip = get_ip() self.running = True self.controls_car = True @@ -20,7 +20,7 @@ def stop(self): self.running = False def display(self): - text = self.name + text = "Ssh to:" + self.ip if check_ssh_connections(): text+= "\n connecté" if self.running: diff --git a/src/HL/programme/module_initialisation.py b/src/HL/programme/module_initialisation.py index b220a91a..80ce0bb3 100644 --- a/src/HL/programme/module_initialisation.py +++ b/src/HL/programme/module_initialisation.py @@ -2,10 +2,11 @@ from src.HL.programme.programme import Program import threading from ..Autotech_constant import SOCKET_ADRESS -import logging as log +import logging class Initialisation(Program): def __init__(self, camera, lidar, tof): super().__init__() + self.log = logging.getLogger(__name__) self.name = "Initialisation:" self.camera = None self.lidar = None @@ -23,37 +24,33 @@ def init_camera(self,camera): try: self.camera = camera() self.camera_init = 1 + self.log.info("Camera initialized successfully") except Exception as e: self.camera_init = 2 - self.error += str(e) - print("-------------------------------------------") - print(self.error) + self.log.error("Camera init error : " + str(e)) def init_lidar(self,lidar): try: self.lidar = lidar(SOCKET_ADRESS["IP"], SOCKET_ADRESS["PORT"]) self.lidar.stop() self.lidar.startContinuous(0, 1080) - log.info("Lidar initialized successfully") + self.log.info("Lidar initialized successfully") self.lidar_init = 1 except Exception as e: self.lidar_init = 2 - self.error += str(e) - print("-------------------------------------------") - print(self.error) + self.log.error("Lidar init error : " + str(e)) def init_tof(self,tof): try: self.tof = tof() self.tof_init = 1 + self.log.info("Camera initialized successfully") except Exception as e: self.tof_init = 2 - self.error += str(e) - print("-------------------------------------------") - print(self.error) + self.log.error("Tof init error : " + str(e)) def display(self): - text = self.name + text = "Initialisation:" text+= "\n camera: " if self.camera_init == 0: diff --git a/src/HL/programme/programme.py b/src/HL/programme/programme.py index 295b0fb6..b5e3d5be 100644 --- a/src/HL/programme/programme.py +++ b/src/HL/programme/programme.py @@ -4,14 +4,13 @@ """ classe type pour tout les programme """ class Program: - name:str - controls_car:bool + controls_car:bool running:bool - vitesse_d:Optional[float] + vitesse_d:Optional[float] # change me to target speed direction_d:Optional[float] def __init__(self): - self.logger = logging.getLogger() + self.logger = logging.getLogger(__name__) self.logger.setLevel(LOGGING_LEVEL) def kill(self): @@ -21,8 +20,9 @@ def start(self): pass def display(self): + name = self.__class__.__name__ if (self.running): - return self.name + "\n" + "(running)" + return f"{name} \n (running)" else: - return self.name + "\n" + return name \ No newline at end of file diff --git a/src/HL/programme/scripts/Driver.py b/src/HL/programme/scripts/Driver.py index 394834c0..375eb5ba 100644 --- a/src/HL/programme/scripts/Driver.py +++ b/src/HL/programme/scripts/Driver.py @@ -4,7 +4,7 @@ from scipy.special import softmax import numpy as np import onnxruntime as ort -import logging as log +import logging from src.HL.Autotech_constant import SPEED_LOOKUP, ANGLE_LOOKUP, MODEL_PATH, Temperature @@ -12,13 +12,14 @@ class Driver: def __init__(self, context_size=0, horizontal_size=0): + self.log = logging.getLogger(__name__) self.context_size = context_size self.horizontal_size = horizontal_size self._loaded = False self.ai_session = None self.context = None - if log.getLogger().isEnabledFor(log.DEBUG): + if self.log.getLogger().isEnabledFor(self.log.DEBUG): self.fig, self.ax = plt.subplots(4, 1, figsize=(10, 8)) self.steering_bars = self.ax[0].bar(range(16), np.zeros(16), color='blue') self.steering_avg = [ @@ -51,11 +52,11 @@ def __init__(self, context_size=0, horizontal_size=0): def load_model(self): if self._loaded: return - log.info("Chargement du modèle IA...") + self.log.info("Chargement du modèle IA...") self.ai_session = ort.InferenceSession(MODEL_PATH) self.context = np.zeros([2, self.context_size, self.horizontal_size], dtype=np.float32 ) self._loaded = True - log.info("Modèle IA chargé") + self.log.info("Modèle IA chargé") def reset(self): self.context = np.zeros([2, self.context_size, self.horizontal_size], dtype=np.float32) @@ -72,7 +73,7 @@ def simple_minded(self, lidar_data): def ai_update_lidar_camera(self, lidar_data, camera_data): if not self._loaded: raise RuntimeError("Driver non initialisé (modèle IA non chargé)") - log.info(f"MIN MAX lidar_data: {(min(lidar_data), max(lidar_data))}") + self.log.info(f"MIN MAX lidar_data: {(min(lidar_data), max(lidar_data))}") lidar_data = sp.ndimage.zoom( np.array(lidar_data, dtype=np.float32), @@ -95,8 +96,8 @@ def ai_update_lidar_camera(self, lidar_data, camera_data): vect_dir = softmax(vect_dir) # distribution de probabilité vect_prop = softmax(vect_prop) - if log.getLogger().isEnabledFor(log.DEBUG): - log.info(f"MIN MAX lidar_data: {(min(lidar_data), max(lidar_data))}") + if self.log.getLogger().isEnabledFor(log.DEBUG): + self.log.info(f"MIN MAX lidar_data: {(min(lidar_data), max(lidar_data))}") self.lidar_img.set_array(np.log(1 + self.context[0])) self.camera_img.set_array(self.context[1]) From 168f5bd7fc4d0d4145dfdb546df6781d1911b772 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 21:44:23 +0100 Subject: [PATCH 098/107] feat: rajout de log partout --- src/HL/Serveur_mq.py | 2 +- src/HL/actionneur_capteur/Camera.py | 1 + src/HL/programme/Poweroff.py | 1 + src/HL/programme/RemoteControl.py | 1 + src/HL/programme/SshProgramme.py | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index d5de1059..a38adcbb 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -103,7 +103,7 @@ def __init__(self): self.programme = [SshProgramme(), self.initialisation_module, Ai_Programme(self), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self), Poweroff()] - self.log.debug("Programmes chargés: %s", [p.name for p in self.programme]) + self.log.debug("Programmes chargés: %s", [type(p).__name__ for p in self.programme]) # donnée de l'écran self.Screen = 0 diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index fe1fcb8e..d79c8b8f 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -8,6 +8,7 @@ import shutil import scipy as sp import time +import logging from picamera2 import Picamera2 from picamera2.encoders import JpegEncoder diff --git a/src/HL/programme/Poweroff.py b/src/HL/programme/Poweroff.py index 17b3fe5b..ad39cbb3 100644 --- a/src/HL/programme/Poweroff.py +++ b/src/HL/programme/Poweroff.py @@ -1,6 +1,7 @@ import subprocess import os from src.HL.programme.programme import Program +import logging class Poweroff(Program): def __init__(self): diff --git a/src/HL/programme/RemoteControl.py b/src/HL/programme/RemoteControl.py index 8c201a93..faf6ef15 100644 --- a/src/HL/programme/RemoteControl.py +++ b/src/HL/programme/RemoteControl.py @@ -3,6 +3,7 @@ import socket import threading import time +import logging class RemoteControl(Program): """ ce programme permet de prendre le control de la voiture à distance en utilsant des packet udp""" diff --git a/src/HL/programme/SshProgramme.py b/src/HL/programme/SshProgramme.py index 14d95e4f..11018895 100644 --- a/src/HL/programme/SshProgramme.py +++ b/src/HL/programme/SshProgramme.py @@ -1,6 +1,6 @@ from src.HL.programme.programme import Program from src.HL.programme.scripts.get_ip import get_ip, check_ssh_connections -import logging as log +import logging class SshProgramme(Program): """montre le menu ssh de la voiture et si séléctionner comme programme force la vitesse et la direction à 0""" def __init__(self): From 8eaf919be0ef01d4289b3de53190a06ff8bffde3 Mon Sep 17 00:00:00 2001 From: cbampeta Date: Fri, 19 Dec 2025 21:54:59 +0100 Subject: [PATCH 099/107] feat: rajout de log partout --- src/HL/Serveur_mq.py | 3 ++- src/HL/programme/Camera_serv.py | 3 +++ src/HL/programme/Car.py | 16 ++++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index a38adcbb..770935b9 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -253,7 +253,7 @@ def envoie_donnee(self, socket): }) elif info["cmd"] == "menu": if info["menu"] in self.programme.key: - start_process(self,info["menu"]) #lancement du menu reçue + self.start_process(self,info["menu"]) #lancement du menu reçue socket.send_json({"status":"ok"}) elif info["get"] == "menu": socket.send_json(self.programme) @@ -351,6 +351,7 @@ def main(self): log_lidar = logging.getLogger("src.HL.actionneur_capteur.Lidar") log_lidar.setLevel(level=logging.INFO) + print([logging.getLogger(name) for name in logging.root.manager.loggerDict]) boot = Serveur() boot.main() diff --git a/src/HL/programme/Camera_serv.py b/src/HL/programme/Camera_serv.py index b3f3f4b5..7c700439 100644 --- a/src/HL/programme/Camera_serv.py +++ b/src/HL/programme/Camera_serv.py @@ -36,6 +36,9 @@ def write(self, buf): class StreamHandler(server.BaseHTTPRequestHandler): def __init__(self): self.log = logging.getLogger(__name__) + + def log_message(self, format, *args): + logging.getLogger(__name__).info(format % args) def do_GET(self): if self.path != "/stream.mjpg": diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 3af02ca7..f6f1e2b9 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -54,7 +54,7 @@ def tof(self): def stop(self): self.vitesse_d = 0 self.direction_d = 0 - log.info("Arrêt du moteur") + self.log.info("Arrêt du moteur") def has_Crashed(self): @@ -64,7 +64,7 @@ def has_Crashed(self): if len(small_distances) > 2: # min_index = self.lidar.rDistance.index(min(small_distances)) while self.tof.get_distance() < REAR_BACKUP_DIST: - log.info(f"Obstacle arriere détecté {self.tof.get_distance()}") + self.log.info(f"Obstacle arriere détecté {self.tof.get_distance()}") self.vitesse_d = 0 time.sleep(0.1) return True @@ -188,28 +188,28 @@ def stop(self): if __name__ == '__main__': Format= '%(asctime)s:%(name)s:%(levelname)s:%(message)s' if input("Appuyez sur D pour démarrer en debug ou sur n'importe quelle autre touche pour démarrer en mode normal") in ("D", "d"): - log.basicConfig(level=log.DEBUG, format=Format) + logging.basicConfig(level=logging.DEBUG, format=Format) else: - log.basicConfig(level=log.INFO, format=Format) + logging.basicConfig(level=logging.INFO, format=Format) bp2 = Button("GPIO6") try: Schumacher = Driver(128, 128) GR86 = Car(Schumacher,None,None) GR86._initialize_camera() GR86._initialize_lidar() - log.info("Initialisation terminée") + logging.info("Initialisation terminée") if input("Appuyez sur D pour démarrer ou tout autre touche pour quitter") in ("D", "d") or bp2.is_pressed: - log.info("Depart") + logging.info("Depart") while True: GR86.main() else: raise Exception("Le programme a été arrêté par l'utilisateur") except KeyboardInterrupt: GR86.stop() - log.info("Le programme a été arrêté par l'utilisateur") + logging.info("Le programme a été arrêté par l'utilisateur") except Exception as e: # catch all exceptions to stop the car GR86.stop() - log.error("Erreur inconnue") + logging.error("Erreur inconnue") raise e # re-raise the exception to see the error message \ No newline at end of file From 73d73218db9f11dc4d62914bb9a5943c3eacab09 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Wed, 24 Dec 2025 22:30:52 +0100 Subject: [PATCH 100/107] =?UTF-8?q?feat:=20suppression=20d'un=20import=20d?= =?UTF-8?q?ans=20serveur=5Fmq=20qui=20servai=20a=20rien=20(np)=20et=20modi?= =?UTF-8?q?fication=20de=20masterI2C=20pour=20pouvoir=20g=C3=A9r=C3=A9=20l?= =?UTF-8?q?a=20connection=20i2c=20=C3=A0=20la=20place=20de=20serveur=5Fmq?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Serveur_mq.py | 1 - src/HL/masterI2C.py | 91 +++++++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 770935b9..fcefc6ec 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -1,6 +1,5 @@ import zmq context = zmq.Context() -import numpy as np import cv2 import time import threading diff --git a/src/HL/masterI2C.py b/src/HL/masterI2C.py index 76b3ea60..832864ca 100644 --- a/src/HL/masterI2C.py +++ b/src/HL/masterI2C.py @@ -1,47 +1,58 @@ -#masteri2c est la pour debug la communication entre l'arduino et la pi. - import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module import time -import numpy as np import struct -# Create an SMBus instance -bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 # I2C address of the slave SLAVE_ADDRESS = 0x08 - -vitesse = 200 # en millimetre par seconde -direction = 100 # en degré - - -def write_vitesse_direction(vitesse,direction): - # Convert string to list of ASCII values - data = struct.pack('= length: - float_values = struct.unpack('f' * num_floats, bytes(data[:length])) - return list(float_values) - else: - raise ValueError("Not enough data received from I2C bus") -if __name__ == "__main__": - while(True): - vitesse= float(input("vitesse en millimetre par seconde:")) - rotation= float(input("rotation en degré:")) - write_vitesse_direction(vitesse,rotation) - time.sleep(0.1) # Wait for the slave to process the data - received = read_data(3) # Adjust length as needed - print("Received from slave:", received[0],received[1], "vitesse voiture",received[2]) - - # Request data from the slave - \ No newline at end of file +class I2c_arduino: + def __init__(self,serveur): + self.log = logging.getLogger(__name__) + self.serveur = serveur + self.vitesse_r = 0 + self.length_i2c_received = 3 + self.send_running = True + self.receive_running = True + self.time_between_received = 0.1 + + #voltage des lipos + self.voltage_lipo = 0 + self.voltage_nimh = 0 + + #initialisation du bus i2c + self.bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 + self.log.info("I2C: bus ouvert sur /dev/i2c-1") + + #initialization of i2c send and received + threading.Thread(target=self.start_send(), daemon=True).start() + threading.Thread(target=self.start_received(), daemon=True).start() + + def start_send(self): + """Envoie vitesse/direction régulièrement au microcontroleur. (toute les frames actuellement)""" + self.log.info("Thread I2C loop démarré") + while self.send_running: + try : + data = struct.pack('= length: + float_values = struct.unpack('f' * self.length_i2c_received, bytes(data[:length])) + list_valeur = list(float_values) + + # on enregistre les valeur + self.voltage_lipo = list_valeur[0] + self.voltage_nimh = list_valeur[1] + self.vitesse_r = list_valeur[2] + else: + self.log.warning("I2C: taille inattendue (%d au lieu de %d)", len(data), length) + time.sleep(self.time_between_received) \ No newline at end of file From 360f3b40ac32bb540032fd32f3dfb7a485ecc17c Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 08:30:36 +0100 Subject: [PATCH 101/107] feat : rajout de constante dans autotech constante et dans Serveur_mq pour plus de personalisation --- src/HL/Autotech_constant.py | 18 +++++++++++++++--- src/HL/Serveur_mq.py | 15 ++++----------- src/HL/programme/Car.py | 2 +- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index a54703a9..142aca85 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -1,9 +1,21 @@ import os import numpy as np -MAX_SOFT_SPEED = 6 # en metre par secondes -MIN_SOFT_SPEED = -4 -MAX_ANGLE = 18 +# controle de la voiture +MAX_IA_SPEED = 2 # maximum speed for ia +MIN_IA_SPEED = -2 # minimum speed for ia +MAX_CONTROL_SPEED = 2 # maximum speed for controling devices +MIN_CONTROL_SPEED = -2 # minimum speed for controlig devices +MAX_ANGLE = 18 # angle between the two extrem position + + +#I2C +I2C_NUMBER_DATA_RECEIVED = 3 # the number of info data sent by the arduino +I2C_SLEEP_RECEIVED = 0.1 # the time between two demand of info data to the arduino +I2C_SLEEP_ERROR_LOOP = 1 # In seconds its the time bettween two try of i2C if an error occurd + + + CRASH_DIST = 110 REAR_BACKUP_DIST = 100 #mm Distance at which the car will NOT reverse due to the obstacle behind it LIDAR_DATA_AMPLITUDE = 1 diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index fcefc6ec..803bea18 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -33,7 +33,7 @@ from src.HL.programme.module_initialisation import Initialisation from src.HL.programme.Car import Ai_Programme - +from Autotech_constant import I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_RECEIVED, I2C_SLEEP_ERROR_LOOP #le nombre de donnée récupéré par l'i2c @@ -65,16 +65,13 @@ def __init__(self): self.led2 = LED("GPIO27") self.buzzer = Buzzer("GPIO26") self.log.info("GPIO: boutons, LEDs, buzzer initialisés") - - self.remote_control = False # on initialise le remote control à False - self.serial = i2c(port=1, address=0x3C) self.device = ssd1306(self.serial) self.bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1 self.log.info("I2C: bus ouvert sur /dev/i2c-1") - self.length_i2c_received = 3 #nombre de donnée à récupéré de l'arduino (voltage lipo, voltage nimh) + self.length_i2c_received = I2C_NUMBER_DATA_RECEIVED #nombre de donnée à récupéré de l'arduino (voltage lipo, voltage nimh) # initialisation des donnnée de la voiture self.vitesse_d = 0 #vitesse demandé par le programme @@ -85,8 +82,6 @@ def __init__(self): self.voltage_nimh = 0 self.vitesse_r = 0 #vitesse réel de la voiture - self.camera_reverse = True - # initialisation des commande de temps self.initial_time = time.time() self.last_cmd_time = time.time() @@ -213,7 +208,7 @@ def i2c_loop(self): self.bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data)) except Exception as e: self.log.error("Erreur I2C write: %s", e, exc_info=True) - time.sleep(1) + time.sleep(I2C_SLEEP_RECEIVED) def i2c_received(self): """récupére les informations de l'arduino""" @@ -232,7 +227,7 @@ def i2c_received(self): self.vitesse_r = list_valeur[2] else: self.log.warning("I2C: taille inattendue (%d au lieu de %d)", len(data), length) - time.sleep(0.1) + time.sleep(I2C_SLEEP_ERROR_LOOP) def envoie_donnee(self, socket): """ on regarde si il s'agit de lappelle pour le control interne @@ -350,7 +345,5 @@ def main(self): log_lidar = logging.getLogger("src.HL.actionneur_capteur.Lidar") log_lidar.setLevel(level=logging.INFO) - print([logging.getLogger(name) for name in logging.root.manager.loggerDict]) - boot = Serveur() boot.main() diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index f6f1e2b9..9748d1b3 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -10,7 +10,7 @@ from src.HL.programme.programme import Program # Import constants from HL.Autotech_constant to share them between files and ease of use -from ..Autotech_constant import MAX_SOFT_SPEED, MAX_ANGLE, CRASH_DIST, MODEL_PATH, SOCKET_ADRESS, REAR_BACKUP_DIST, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET +from ..Autotech_constant import MAX_ANGLE, CRASH_DIST, MODEL_PATH, SOCKET_ADRESS, REAR_BACKUP_DIST, LIDAR_DATA_SIGMA, LIDAR_DATA_AMPLITUDE, LIDAR_DATA_OFFSET from src.HL.programme.scripts.Driver import Driver From e8e7e31752e8d71168db071edddfd267fa4fa368 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 09:21:01 +0100 Subject: [PATCH 102/107] =?UTF-8?q?feat:=20rajout=20de=20Constante=20dans?= =?UTF-8?q?=20autotech=20constante=20et=20chnagement=20des=20programmes=20?= =?UTF-8?q?pour=20les=20utilis=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Autotech_constant.py | 3 ++- src/HL/masterI2C.py | 12 +++++------- src/HL/programme/RemoteControl.py | 7 +++---- src/HL/programme/module_initialisation.py | 6 ++---- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index 142aca85..6699c3ee 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -14,7 +14,8 @@ I2C_SLEEP_RECEIVED = 0.1 # the time between two demand of info data to the arduino I2C_SLEEP_ERROR_LOOP = 1 # In seconds its the time bettween two try of i2C if an error occurd - +#Remote control +PORT_REMOTE_CONTROL = 5556 CRASH_DIST = 110 REAR_BACKUP_DIST = 100 #mm Distance at which the car will NOT reverse due to the obstacle behind it diff --git a/src/HL/masterI2C.py b/src/HL/masterI2C.py index 832864ca..ca8fcfb3 100644 --- a/src/HL/masterI2C.py +++ b/src/HL/masterI2C.py @@ -1,7 +1,7 @@ import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module import time import struct - +from Autotech_constant import I2C_SLEEP_RECEIVED, I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_ERROR_LOOP # I2C address of the slave SLAVE_ADDRESS = 0x08 @@ -10,10 +10,8 @@ def __init__(self,serveur): self.log = logging.getLogger(__name__) self.serveur = serveur self.vitesse_r = 0 - self.length_i2c_received = 3 self.send_running = True self.receive_running = True - self.time_between_received = 0.1 #voltage des lipos self.voltage_lipo = 0 @@ -36,17 +34,17 @@ def start_send(self): self.bus.write_i2c_block_data(SLAVE_ADDRESS, 0, list(data)) except Exception as e: self.log.error("Erreur I2C write: %s", e, exc_info=True) - time.sleep(1) + time.sleep(I2C_SLEEP_ERROR_LOOP) def start_received(self): """récupére les informations de l'arduino""" self.log.info("Thread I2C receive démarré") - length = self.length_i2c_received * 4 + length = I2C_NUMBER_DATA_RECEIVED * 4 while self.receive_running: data = self.bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length) # Convert the byte data to a float if len(data) >= length: - float_values = struct.unpack('f' * self.length_i2c_received, bytes(data[:length])) + float_values = struct.unpack('f' * I2C_NUMBER_DATA_RECEIVED, bytes(data[:length])) list_valeur = list(float_values) # on enregistre les valeur @@ -55,4 +53,4 @@ def start_received(self): self.vitesse_r = list_valeur[2] else: self.log.warning("I2C: taille inattendue (%d au lieu de %d)", len(data), length) - time.sleep(self.time_between_received) \ No newline at end of file + time.sleep(I2C_SLEEP_RECEIVED) \ No newline at end of file diff --git a/src/HL/programme/RemoteControl.py b/src/HL/programme/RemoteControl.py index faf6ef15..f53d3cdc 100644 --- a/src/HL/programme/RemoteControl.py +++ b/src/HL/programme/RemoteControl.py @@ -4,7 +4,7 @@ import threading import time import logging - +from src.HL.Autotech_constant import PORT_REMOTE_CONTROL class RemoteControl(Program): """ ce programme permet de prendre le control de la voiture à distance en utilsant des packet udp""" def __init__(self): @@ -18,13 +18,12 @@ def __init__(self): #initialisation self.public = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.public.bind(("0.0.0.0", 5556)) + self.public.bind(("0.0.0.0", PORT_REMOTE_CONTROL)) self.log.info("Initialisation de Remote control fini") def car_controle(self,sock): - """ on regarde si il s'agit de lappelle pour le control interne - (is_private) ou si on veux prendre le controle depuis le pc.""" + """lance le controle depuis le pc.""" sock.settimeout(0.1) while self.running: diff --git a/src/HL/programme/module_initialisation.py b/src/HL/programme/module_initialisation.py index 80ce0bb3..79a2b1f8 100644 --- a/src/HL/programme/module_initialisation.py +++ b/src/HL/programme/module_initialisation.py @@ -7,7 +7,6 @@ class Initialisation(Program): def __init__(self, camera, lidar, tof): super().__init__() self.log = logging.getLogger(__name__) - self.name = "Initialisation:" self.camera = None self.lidar = None self.tof = None @@ -50,9 +49,8 @@ def init_tof(self,tof): self.log.error("Tof init error : " + str(e)) def display(self): - text = "Initialisation:" - - text+= "\n camera: " + + text = "\n camera: " if self.camera_init == 0: text += "(en cour)" elif self.camera_init == 1: From f46f8e80edd018734fea7a81578ffb729779727a Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 09:32:43 +0100 Subject: [PATCH 103/107] feat: rajout de constant pour le stream de la camera --- src/HL/Autotech_constant.py | 14 +++++++++++++- src/HL/actionneur_capteur/Camera.py | 9 +++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index 6699c3ee..995da9ec 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -13,12 +13,24 @@ I2C_NUMBER_DATA_RECEIVED = 3 # the number of info data sent by the arduino I2C_SLEEP_RECEIVED = 0.1 # the time between two demand of info data to the arduino I2C_SLEEP_ERROR_LOOP = 1 # In seconds its the time bettween two try of i2C if an error occurd +SLAVE_ADDRESS = 0x08 # Adresse of the arduino i2c port #Remote control PORT_REMOTE_CONTROL = 5556 +#Camera +PORT_STREAMING_CAMERA = 8000 +SIZE_CAMERA_X = 1280 +SIZE_CAMERA_Y = 720 +FRAME_RATE = 30 +CAMERA_QUALITY = 10 # the more the better but slow the speed of the stream +STREAM_PATH = "stream" + +#Car CRASH_DIST = 110 REAR_BACKUP_DIST = 100 #mm Distance at which the car will NOT reverse due to the obstacle behind it + +#Lidar LIDAR_DATA_AMPLITUDE = 1 LIDAR_DATA_SIGMA = 45 LIDAR_DATA_OFFSET = 0.5 @@ -26,7 +38,7 @@ script_dir = os.path.dirname(os.path.abspath(__file__)) MODEL_PATH = os.path.join(script_dir, "model_CNN1D.onnx") # Allows the model to be loaded from the same directory as the script regardless of the current working directory (aka where the script is run from) -SLAVE_ADDRESS = 0x08 + SOCKET_ADRESS = { "IP": '192.168.0.10', "PORT": 10940 diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index d79c8b8f..f8c688b1 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -41,6 +41,7 @@ def outputframe(self, frame, keyframe=True): from src.HL.programme.Camera_serv import StreamServer, StreamHandler, StreamOutput, frame_buffer from src.HL.programme.programme import Program +from src.HL.Autotech_constant import PORT_STREAMING_CAMERA, SIZE_CAMERA_X, SIZE_CAMERA_Y, FRAME_RATE, CAMERA_QUALITY, STREAM_PATH class ProgramStreamCamera(Program): def __init__(self,serveur): @@ -74,7 +75,7 @@ def kill(self): class Camera: - def __init__(self, size=(1280, 720), port=8000): + def __init__(self, size=(SIZE_CAMERA_X, SIZE_CAMERA_Y), port=PORT_STREAMING_CAMERA): self.size = size self.port = port @@ -98,14 +99,14 @@ def _start_local_capture(self): self.picam2 = Picamera2() config = self.picam2.create_video_configuration( main={"size": self.size}, # plus large, moins zoomé - controls={"FrameRate": 30} # FPS stable + controls={"FrameRate": FRAME_RATE} # FPS stable ) self.picam2.configure(config) self.output = StreamOutput() # Qualité JPEG custom - self.picam2.start_recording(JpegEncoder(q=10), FileOutput(self.output)) + self.picam2.start_recording(JpegEncoder(q=CAMERA_QUALITY), FileOutput(self.output)) # thread lecture last_frame self.capture_thread = threading.Thread( @@ -138,7 +139,7 @@ def start_stream(self): self.httpd = StreamServer(("", self.port), StreamHandler) def run_server(): - print(f"[INFO] MJPEG stream on http://:{self.port}/stream.mjpg") + print(f"[INFO] MJPEG stream on http://:{self.port}/{STREAM_PATH}.mjpg") try: self.httpd.serve_forever() except Exception as e: From d8a554c82168de7a2512acae1502672ba6fb4ca1 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 16:14:58 +0100 Subject: [PATCH 104/107] fix: enlevage de name= main dans car.py car non fonctionnelle en attendant den refaire un bien --- src/HL/programme/Car.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 9748d1b3..11626ec2 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -184,8 +184,8 @@ def stop(self): self.running = False self.GR86.stop() - -if __name__ == '__main__': +""" +if __name__ == '__main__': # non fonctionnelle Format= '%(asctime)s:%(name)s:%(levelname)s:%(message)s' if input("Appuyez sur D pour démarrer en debug ou sur n'importe quelle autre touche pour démarrer en mode normal") in ("D", "d"): logging.basicConfig(level=logging.DEBUG, format=Format) @@ -212,4 +212,4 @@ def stop(self): GR86.stop() logging.error("Erreur inconnue") raise e # re-raise the exception to see the error message - \ No newline at end of file + """ \ No newline at end of file From 1c659c2d6eda6ec948a6664eef08d2c7c43c5386 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 16:22:01 +0100 Subject: [PATCH 105/107] =?UTF-8?q?feat:=20rajout=20de=20commentaire=20dan?= =?UTF-8?q?s=20Autotech=5Fconstante=20et=20suppression=20du=20fichier=20te?= =?UTF-8?q?st=5Fserveur=20qui=20na=20plus=20lieux=20d'=C3=AAtre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HL/Autotech_constant.py | 13 +++--- src/HL/test_serveur.py | 91 ------------------------------------- 2 files changed, 7 insertions(+), 97 deletions(-) delete mode 100644 src/HL/test_serveur.py diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index 995da9ec..ad558812 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -1,7 +1,7 @@ import os import numpy as np -# controle de la voiture +# Car control MAX_IA_SPEED = 2 # maximum speed for ia MIN_IA_SPEED = -2 # minimum speed for ia MAX_CONTROL_SPEED = 2 # maximum speed for controling devices @@ -16,15 +16,16 @@ SLAVE_ADDRESS = 0x08 # Adresse of the arduino i2c port #Remote control -PORT_REMOTE_CONTROL = 5556 +PORT_REMOTE_CONTROL = 5556 # Port to send data for remote control on :PORT_REMOTE_CONTROL #Camera -PORT_STREAMING_CAMERA = 8000 +PORT_STREAMING_CAMERA = 8000 # adresse where to see the stream of the camera if activate is :PORT_STREAMIN_CAMERA/STREAM_PATH.jpeg +STREAM_PATH = "stream" SIZE_CAMERA_X = 1280 SIZE_CAMERA_Y = 720 -FRAME_RATE = 30 -CAMERA_QUALITY = 10 # the more the better but slow the speed of the stream -STREAM_PATH = "stream" +FRAME_RATE = 30 # frame rate of the camera +CAMERA_QUALITY = 10 # the more the better but slow the speed of the stream (10 its passable) + #Car CRASH_DIST = 110 diff --git a/src/HL/test_serveur.py b/src/HL/test_serveur.py deleted file mode 100644 index 6c22757a..00000000 --- a/src/HL/test_serveur.py +++ /dev/null @@ -1,91 +0,0 @@ -import zmq -import base64 -from io import BytesIO -from PIL import Image -import time -import numpy as np -# on envoie les données au serveur -PI_IP = "192.168.1.10" # mets la bonne IP - -context = zmq.Context() -socket = context.socket(zmq.PULL) -socket.connect(f"tcp://{PI_IP}:6001") -def get_camera_frame(): - socket.send_json({"cmd": "cam"}) - reply = socket.recv_json() - - if reply["cam"] is None: - print("Image not ready") - return None - - jpg_bytes = base64.b64decode(reply["cam"]) # <-- aligné ici - img = Image.open(BytesIO(jpg_bytes)) - return img - -""" -context = zmq.Context() -socket = context.socket(zmq.REQ) -socket.connect("tcp://127.0.0.1:5557") - -def recoit_donnee(): - socket.send_json({"cmd": "info"}) - resp = socket.recv_json() - print(resp) - -rDistance = None -xTheta = None - -def startPlotter(self, autorange=False): - def toCartesian(xTheta, xR): - X = np.cos(xTheta) * xR - Y = np.sin(xTheta) * xR - return X,Y - - plt.show() - fig = plt.figure() - axc = plt.subplot(121) - axp = plt.subplot(122, projection='polar') - # axp.set_thetamax(deg2theta(45)) - # axp.set_thetamax(deg2theta(270 + 45)) - axp.grid(True) - log.info('Plotter started, press any key to exit') - - log.debug(f'{xTheta}, {rDistance}') - while True: - X, Y = toCartesian(xTheta, rDistance) - - axp.clear() - axc.clear() - - axp.plot(xTheta, rDistance) - - axc.plot(X, Y) - - if not autorange: - axp.set_rmax(8000) - axc.set_xlim(-5000, 5000) - axc.set_ylim(-5000, 5000) - - plt.pause(1e-17) - - if plt.waitforbuttonpress(timeout=0.02): - os._exit(0) - -""" -import cv2 - -cap = cv2.VideoCapture("tcp://192.168.1.10:6002") - - -if __name__ == "__main__": - while(True): - ret, frame = cap.read() - if not ret: - print("No frame…") - continue - - cv2.imshow("RPI H264 60fps", frame) - if cv2.waitKey(1) == 27: - break - - # Request data from the slave \ No newline at end of file From 612b53a0034d23da39b8c86056d6c71a77af49c2 Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Fri, 26 Dec 2025 16:41:50 +0100 Subject: [PATCH 106/107] =?UTF-8?q?feat:=20changement=20pour=20=C3=AAue=20?= =?UTF-8?q?le=20script=20se=20lace=20mme=20si=20il=20est=20toujours=20pas?= =?UTF-8?q?=20connecter=20=C3=A0=20un=20r=C3=A9seaux=20et=20affiche=20sur?= =?UTF-8?q?=20l'=C3=A9cran=20lorsqu'il=20est=20connect=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/startup.sh | 5 ---- src/HL/programme/SshProgramme.py | 46 +++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/scripts/startup.sh b/scripts/startup.sh index 5892df06..fbe10ef9 100755 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -4,11 +4,6 @@ export PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" export PYTHONPATH=$PYTHONPATH:/home/intech/CoVAPSy -# Wait until WiFi is acquired -while ! ping -c 1 google.com &> /dev/null; do - echo "Waiting for WiFi connection..." - sleep 5 -done # Change to the project directory cd /home/intech/CoVAPSy diff --git a/src/HL/programme/SshProgramme.py b/src/HL/programme/SshProgramme.py index 11018895..b9e589b2 100644 --- a/src/HL/programme/SshProgramme.py +++ b/src/HL/programme/SshProgramme.py @@ -1,28 +1,54 @@ from src.HL.programme.programme import Program -from src.HL.programme.scripts.get_ip import get_ip, check_ssh_connections -import logging +from src.HL.programme.scripts.get_ip import check_ssh_connections +import socket +import time + class SshProgramme(Program): - """montre le menu ssh de la voiture et si séléctionner comme programme force la vitesse et la direction à 0""" + """Montre le menu SSH de la voiture et force vitesse/direction à 0""" + def __init__(self): super().__init__() - self.ip = get_ip() self.running = True self.controls_car = True self.vitesse_d = 0 self.direction_d = 0 - + + # Cache IP + self.ip = None + self._last_ip_check = 0 + self._ip_refresh_interval = 1.0 # secondes def start(self): self.running = True - + def stop(self): self.running = False + def _update_ip_if_needed(self): + now = time.monotonic() + if now - self._last_ip_check >= self._ip_refresh_interval: + self.ip = self.get_local_ip() + self._last_ip_check = now + + @staticmethod + def get_local_ip(): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(0.1) + s.connect(("10.255.255.255", 1)) + ip = s.getsockname()[0] + s.close() + return ip + except Exception: + return None + def display(self): - text = "Ssh to:" + self.ip + self._update_ip_if_needed() + + text = f"Ssh to: {self.ip or 'non connecté'}" if check_ssh_connections(): - text+= "\n connecté" + text += "\n connecté" if self.running: - text+= "\n Voiture en stand by" - return text \ No newline at end of file + text += "\n Voiture en stand by" + return text From 14d26e66c025ad9a9d5009ee23eedf3067c4bbfd Mon Sep 17 00:00:00 2001 From: Cbampeta Date: Mon, 29 Dec 2025 08:30:21 +0100 Subject: [PATCH 107/107] feat : enlevage de tout les .name dans les Programmes --- scripts/commande_PS4.py | 1 - src/HL/Autotech_constant.py | 5 +++++ src/HL/Serveur_mq.py | 19 ++++--------------- src/HL/actionneur_capteur/Camera.py | 1 - src/HL/masterI2C.py | 4 +--- src/HL/programme/Car.py | 2 -- src/HL/programme/Poweroff.py | 1 - src/HL/programme/RemoteControl.py | 4 ++-- src/HL/programme/module_initialisation.py | 3 ++- src/HL/programme/programme.py | 8 ++++---- 10 files changed, 18 insertions(+), 30 deletions(-) diff --git a/scripts/commande_PS4.py b/scripts/commande_PS4.py index 5ae3a14c..f0a8dbde 100644 --- a/scripts/commande_PS4.py +++ b/scripts/commande_PS4.py @@ -42,7 +42,6 @@ class PS4ControllerProgram(Program): def __init__(self): super().__init__() self.log = logging.getLogger(__name__) - self.name = "PS4 Controller" self.running = False self.controls_car = True diff --git a/src/HL/Autotech_constant.py b/src/HL/Autotech_constant.py index ad558812..cc72528e 100644 --- a/src/HL/Autotech_constant.py +++ b/src/HL/Autotech_constant.py @@ -36,6 +36,11 @@ LIDAR_DATA_SIGMA = 45 LIDAR_DATA_OFFSET = 0.5 +# Screen car +TEXT_HEIGHT = 11 +TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff + + script_dir = os.path.dirname(os.path.abspath(__file__)) MODEL_PATH = os.path.join(script_dir, "model_CNN1D.onnx") # Allows the model to be loaded from the same directory as the script regardless of the current working directory (aka where the script is run from) diff --git a/src/HL/Serveur_mq.py b/src/HL/Serveur_mq.py index 803bea18..2cb54509 100644 --- a/src/HL/Serveur_mq.py +++ b/src/HL/Serveur_mq.py @@ -33,17 +33,8 @@ from src.HL.programme.module_initialisation import Initialisation from src.HL.programme.Car import Ai_Programme -from Autotech_constant import I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_RECEIVED, I2C_SLEEP_ERROR_LOOP +from Autotech_constant import I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_RECEIVED, I2C_SLEEP_ERROR_LOOP, TEXT_HEIGHT, TEXT_LEFT_OFFSET - #le nombre de donnée récupéré par l'i2c - - -TEXT_HEIGHT = 11 -TEXT_LEFT_OFFSET = 3 # Offset from the left of the screen to ensure no cuttoff - - -private = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -private.bind(("127.0.0.1", 5555)) # on utilise tcp pour les infos des différents informations telemetry = context.socket(zmq.REP) @@ -57,7 +48,7 @@ def __init__(self): #initialisation des différents module qui tourne tout le temps self.log.info("Initialisation du serveur") - + # initialisation des boutons et de l'i2c self.bp_next = Button("GPIO5", bounce_time=0.1) self.bp_entre = Button("GPIO6", bounce_time=0.1) @@ -94,8 +85,6 @@ def __init__(self): self.initialisation_module = Initialisation(Camera,Lidar,ToF) - - self.programme = [SshProgramme(), self.initialisation_module, Ai_Programme(self), PS4ControllerProgram(), RemoteControl(), ProgramStreamCamera(self), Poweroff()] self.log.debug("Programmes chargés: %s", [type(p).__name__ for p in self.programme]) @@ -268,7 +257,7 @@ def start_process(self,num_programme): sinon le programme est lancé ou tué celon si il était déjà lancé ou tué avant""" self.log.info("Action utilisateur: programme %d (%s)", num_programme, - self.programme[num_programme].name) + type(self.programme[num_programme]).__name__) if self.programme[num_programme].running: self.programme[num_programme].kill() if self.programme[num_programme].controls_car: @@ -281,7 +270,7 @@ def start_process(self,num_programme): self.log.info("Arrêt du programme %s", - self.programme[num_programme].name) + type(self.programme[num_programme]).__name__) elif self.programme[num_programme].controls_car: self.programme[self.last_programme_control].kill() diff --git a/src/HL/actionneur_capteur/Camera.py b/src/HL/actionneur_capteur/Camera.py index f8c688b1..35ed39e8 100644 --- a/src/HL/actionneur_capteur/Camera.py +++ b/src/HL/actionneur_capteur/Camera.py @@ -47,7 +47,6 @@ class ProgramStreamCamera(Program): def __init__(self,serveur): super().__init__() self.log = logging.getLogger(__name__) - self.name = "Streaming Video" self.serveur = serveur self.running = False self.controls_car = False diff --git a/src/HL/masterI2C.py b/src/HL/masterI2C.py index ca8fcfb3..30ff1e62 100644 --- a/src/HL/masterI2C.py +++ b/src/HL/masterI2C.py @@ -1,9 +1,7 @@ import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module import time import struct -from Autotech_constant import I2C_SLEEP_RECEIVED, I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_ERROR_LOOP -# I2C address of the slave -SLAVE_ADDRESS = 0x08 +from Autotech_constant import I2C_SLEEP_RECEIVED, I2C_NUMBER_DATA_RECEIVED, I2C_SLEEP_ERROR_LOOP, SLAVE_ADDRESS class I2c_arduino: def __init__(self,serveur): diff --git a/src/HL/programme/Car.py b/src/HL/programme/Car.py index 11626ec2..46b6a23f 100644 --- a/src/HL/programme/Car.py +++ b/src/HL/programme/Car.py @@ -130,8 +130,6 @@ class Ai_Programme(Program): def __init__(self, serveur): super().__init__() self.log = logging.getLogger(__name__) - self.name = "IA autonome" - self.serveur = serveur self.driver = None self.GR86 = None diff --git a/src/HL/programme/Poweroff.py b/src/HL/programme/Poweroff.py index ad39cbb3..c82ca9dd 100644 --- a/src/HL/programme/Poweroff.py +++ b/src/HL/programme/Poweroff.py @@ -7,7 +7,6 @@ class Poweroff(Program): def __init__(self): super().__init__() self.log = logging.getLogger(__name__) - self.name = "Power off" self.controls_car = False self.running = False diff --git a/src/HL/programme/RemoteControl.py b/src/HL/programme/RemoteControl.py index f53d3cdc..c9e33617 100644 --- a/src/HL/programme/RemoteControl.py +++ b/src/HL/programme/RemoteControl.py @@ -6,11 +6,11 @@ import logging from src.HL.Autotech_constant import PORT_REMOTE_CONTROL class RemoteControl(Program): - """ ce programme permet de prendre le control de la voiture à distance en utilsant des packet udp""" + """ ce programme permet de prendre le control de la voiture à distance en utilsant des packet udp + on peut prendre le controle avec le script remote_controle_controller.py""" def __init__(self): super().__init__() self.log = logging.getLogger(__name__) - self.name = "Remote Control" self.controls_car = True self.running = False self.vitesse_d = 0 diff --git a/src/HL/programme/module_initialisation.py b/src/HL/programme/module_initialisation.py index 79a2b1f8..2261f762 100644 --- a/src/HL/programme/module_initialisation.py +++ b/src/HL/programme/module_initialisation.py @@ -3,6 +3,7 @@ import threading from ..Autotech_constant import SOCKET_ADRESS import logging + class Initialisation(Program): def __init__(self, camera, lidar, tof): super().__init__() @@ -13,7 +14,7 @@ def __init__(self, camera, lidar, tof): self.camera_init = 0 self.lidar_init = 0 self.tof_init = 0 - self.error = "" + threading.Thread(target=self.init_camera, args=(camera,), daemon=True).start() threading.Thread(target=self.init_lidar, args=(lidar,), daemon=True).start() threading.Thread(target=self.init_tof, args=(tof,), daemon=True).start() diff --git a/src/HL/programme/programme.py b/src/HL/programme/programme.py index b5e3d5be..990b21ec 100644 --- a/src/HL/programme/programme.py +++ b/src/HL/programme/programme.py @@ -4,10 +4,10 @@ """ classe type pour tout les programme """ class Program: - controls_car:bool - running:bool - vitesse_d:Optional[float] # change me to target speed - direction_d:Optional[float] + controls_car:bool # correspond si le programme cotronle la voiture ou non pour savoir si il faut arreter l'ancien programme qui controle la voiture + running:bool # état de base du programme (au lancement de la voiture) + vitesse_d:Optional[float] # target speed + direction_d:Optional[float] # target direction def __init__(self): self.logger = logging.getLogger(__name__)