Compare commits

...

15 Commits

Author SHA1 Message Date
cc31254055 1.增加xbox控制器和飞行手柄控制器
2.增加多臂多控制器模式
3.末端姿态由欧拉角控制切换到四元数控制
4.增加vr手柄控制器

Signed-off-by: 1002142102@qq.com <1002142102@qq.com>
2025-12-24 14:02:34 +08:00
becdc2c894 修复不能移动 2025-12-11 10:07:37 +08:00
d038612734 修复初始位姿初始化错误 2025-12-10 17:21:54 +08:00
dce4e8ad8a 优化飞行手柄 2025-12-10 14:46:21 +08:00
951b4ba458 增加仿真模式控制 2025-12-10 11:49:13 +08:00
39d860c7ee 优化手柄控制 2025-12-10 11:46:28 +08:00
450383cabb youhuaxiangji 2025-12-10 09:36:49 +08:00
4e29a3926d 增加配置文件忽略 2025-12-09 17:06:15 +08:00
7eb48bfa8f 修复控制 2025-12-09 16:28:18 +08:00
cc79fb5656 优化远控 2025-12-09 16:13:41 +08:00
e03883f059 修复Robotic_Armsdk版本问题 2025-12-09 14:55:24 +08:00
2ee2c7fbb2 Merge branch 'robot_client' of https://git.matai.center/tangger/lerobot into robot_client 2025-12-09 14:44:23 +08:00
33674795c6 删除文件 2025-12-09 14:44:20 +08:00
0fae637b76 Merge branch 'robot_client' of https://git.matai.center/tangger/lerobot into robot_client 2025-12-09 14:33:22 +08:00
b8a76bab69 xiufu 2025-12-09 14:29:12 +08:00
35 changed files with 1595 additions and 12864 deletions

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
.vscode .vscode
.py .py
*.pyc *.pyc
.venv .venv
.env
test_data

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3
config/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*
!.gitignore
!*.example.yml

View File

@@ -1,6 +1,6 @@
type: realman type: realman
port: 192.168.3.18:8080 port: 127.0.0.1:8800
mock: True mock: False
mode: 1 mode: 1
gripper_range: gripper_range:
- 10 - 10
@@ -9,31 +9,31 @@ motors:
joint_1: joint_1:
id: 1 id: 1
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
joint_2: joint_2:
id: 2 id: 2
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
joint_3: joint_3:
id: 3 id: 3
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
joint_4: joint_4:
id: 4 id: 4
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
joint_5: joint_5:
id: 5 id: 5
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
joint_6: joint_6:
id: 6 id: 6
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
gripper: gripper:
id: 7 id: 7
model: realman model: realman
norm_mode: DEGREES norm_mode: degrees
# cameras: # cameras:
# left: # left:
# serial_number_or_name: 153122077516 # serial_number_or_name: 153122077516
@@ -54,10 +54,10 @@ motors:
# height: 480 # height: 480
# use_depth: False # use_depth: False
joint: joint:
- -90 - 15
- 90 - 90
- 90 - 10
- 90 - 80
- 90 - 110
- -90 - 0
- 10 - 10

View File

@@ -5,4 +5,5 @@ dataset:
single_task: test single_task: test
repo_id: yehao/realman-test repo_id: yehao/realman-test
num_episodes: 2 num_episodes: 2
fps: 2 fps: 30
push_to_hub: false

View File

@@ -0,0 +1,3 @@
robot: !include realman.yml
teleop:
type: xbox

View File

@@ -6,5 +6,24 @@ readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
"lerobot>=0.4.2", "lerobot>=0.4.2",
"Robotic_Arm==1.1.3",
"pygame==2.6.1", "pygame==2.6.1",
] "pyrealsense2>=2.56.5.9235",
"xrobotoolkit-sdk",
"websockets>=15.0.1",
"dotenv>=0.9.9",
"fastapi>=0.124.4",
"uvicorn>=0.38.0",
"flameprof>=0.4",
"scipy>=1.16.3",
"meshcat>=0.3.2",
]
[tool.setuptools]
packages = ["robot_client"]
[tool.uv.sources]
xrobotoolkit-sdk = [
{ path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-win_amd64.whl", marker = "sys_platform == 'win32'" },
{ path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-linux_x86_64.whl", marker = "sys_platform != 'win32'" }
]

Binary file not shown.

View File

@@ -79,7 +79,6 @@ from lerobot.datasets.utils import build_dataset_frame, combine_feature_dicts
from lerobot.datasets.video_utils import VideoEncodingManager from lerobot.datasets.video_utils import VideoEncodingManager
from lerobot.policies.factory import make_policy, make_pre_post_processors from lerobot.policies.factory import make_policy, make_pre_post_processors
from lerobot.policies.pretrained import PreTrainedPolicy from lerobot.policies.pretrained import PreTrainedPolicy
from lerobot.policies.utils import make_robot_action
from lerobot.processor import ( from lerobot.processor import (
PolicyAction, PolicyAction,
PolicyProcessorPipeline, PolicyProcessorPipeline,
@@ -127,6 +126,8 @@ from lerobot.utils.utils import (
from lerobot.utils.visualization_utils import init_rerun, log_rerun_data from lerobot.utils.visualization_utils import init_rerun, log_rerun_data
from robot_client.robots.realman import RealmanRobot,RealmanRobotConfig from robot_client.robots.realman import RealmanRobot,RealmanRobotConfig
from robot_client.teleoperators.xbox import Xbox,XboxConfig from robot_client.teleoperators.xbox import Xbox,XboxConfig
from robot_client.teleoperators.flight_stick import FlightStick,FlightStickConfig
@dataclass @dataclass

View File

@@ -0,0 +1,3 @@
from .robot_mix import MixRobot
from .config import MixRobotConfig
__all__ = ["MixRobot", "MixRobotConfig"]

View File

@@ -0,0 +1,8 @@
from dataclasses import dataclass, field
from lerobot.robots.config import RobotConfig
@RobotConfig.register_subclass("mix")
@dataclass
class MixRobotConfig(RobotConfig):
# Port to connect to the arm
robotList: dict[str,RobotConfig] = field(default_factory=dict[str,RobotConfig])

View File

@@ -0,0 +1,98 @@
import logging
from functools import cached_property
import time
from typing import Any
from .config import MixRobotConfig
from lerobot.robots.robot import Robot
from lerobot.utils.errors import DeviceNotConnectedError
from lerobot.robots import Robot,make_robot_from_config
logger = logging.getLogger(__name__)
class MixRobot(Robot):
config_class = MixRobotConfig
name = "mix"
def __init__(self, config: MixRobotConfig):
super().__init__(config)
self.config = config
self.robotList = {}
for name,config in self.config.robotList.items():
self.robotList[name] = make_robot_from_config(config)
@property
def _motors_ft(self) -> dict[str, type]:
ret = {}
for name,robot in self.robotList.items():
for pname,motor in robot._motors_ft:
pname = pname.replace(".pos", "")
ret[f"{pname}_{name}.pos"] = motor
return ret
@property
def _cameras_ft(self) -> dict[str, tuple]:
ret = {}
for name,robot in self.robotList.items():
for pname,cam in robot._cameras_ft:
ret[f"{pname}.{name}"] = cam
return ret
@cached_property
def observation_features(self) -> dict[str, type | tuple]:
return {**self._motors_ft, **self._cameras_ft}
@cached_property
def action_features(self) -> dict[str, type]:
ret = {}
for name,robot in self.robotList.items():
for pname,typeVal in robot.action_features.items():
ret[f"{name}.{pname}"] = typeVal
return ret
@property
def is_connected(self) -> bool:
return all([robot.is_connected for robot in self.robotList.values()])
def connect(self, calibrate: bool = True) -> None:
for name,robot in self.robotList.items():
robot.connect(calibrate)
@property
def is_calibrated(self) -> bool:
return all([robot.is_calibrated for robot in self.robotList.values()])
def calibrate(self) -> None:
pass
def configure(self) -> None:
pass
def setup_motors(self) -> None:
pass
def get_observation(self) -> dict[str, Any]:
if not self.is_connected:
raise DeviceNotConnectedError(f"{self} is not connected.")
obs_dict = {}
for name,robot in self.robotList.items():
obs_dict.update({f"{name}.{kname}":item for kname,item in robot.get_observation().items()})
return obs_dict
def send_action(self, action: dict[str, Any]) -> dict[str, Any]:
if not self.is_connected:
raise DeviceNotConnectedError(f"{self} is not connected.")
dic = {}
for key,value in action.items():
name = key.split(".")[0]
if name not in dic:
dic[name] = {}
dic[name][key.removeprefix(name+".")] = value
for dname,dvalue in dic.items():
if dname not in self.robotList:
continue
self.robotList[dname].send_action(dvalue)
def disconnect(self):
if not self.is_connected:
raise DeviceNotConnectedError(f"{self} is not connected.")
for name,robot in self.robotList.items():
robot.disconnect()

View File

@@ -1,5 +1,4 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.cameras.configs import CameraConfig
from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig
from lerobot.motors.motors_bus import Motor, MotorCalibration from lerobot.motors.motors_bus import Motor, MotorCalibration
from lerobot.robots.config import RobotConfig from lerobot.robots.config import RobotConfig
@@ -9,7 +8,7 @@ from lerobot.robots.config import RobotConfig
class RealmanRobotConfig(RobotConfig): class RealmanRobotConfig(RobotConfig):
# Port to connect to the arm # Port to connect to the arm
port: str port: str
mock: bool = field(default_factory=bool)\ mock: bool = field(default_factory=bool)
#0关节角度透传模式 1:笛卡尔速度透传 #0关节角度透传模式 1:笛卡尔速度透传
mode: int = 0 mode: int = 0
gripper_range: list[int] = field(default_factory=list) gripper_range: list[int] = field(default_factory=list)
@@ -18,5 +17,7 @@ class RealmanRobotConfig(RobotConfig):
# cameras # cameras
cameras: dict[str, RealSenseCameraConfig] = field(default_factory=dict) cameras: dict[str, RealSenseCameraConfig] = field(default_factory=dict)
joint: list=field(default_factory=list) joint: list=field(default_factory=list)
udp_ip: str|None = "127.0.0.1"
udp_port: int = 8090
motors: dict[str, Motor] = field(default_factory=dict) motors: dict[str, Motor] = field(default_factory=dict)
calibration: dict[str, MotorCalibration] | None = None calibration: dict[str, MotorCalibration] | None = None

View File

@@ -1,56 +1,15 @@
import threading
import time import time
from typing import Any, Dict from typing import Any, Dict
from Robotic_Arm.rm_robot_interface import * from Robotic_Arm.rm_robot_interface import *
from lerobot.motors import Motor, MotorCalibration, MotorsBus from lerobot.motors import Motor, MotorCalibration, MotorsBus
from .robot_mock import RealmanMock
from scipy.spatial.transform import Rotation as R
import numpy
#动作执行成功 #动作执行成功
ACTION_SUCCESS = 0 ACTION_SUCCESS = 0
class RoboticArmMock:
def __init__(self,*args):
pass
def rm_create_robot_arm(self, ip, port):
print(f"connnect {ip}:{port}")
return {"id":1}
def rm_movej(self,*args):
print(f"rm_movej:{args}")
def rm_movej_follow(self,*args):
print(f"rm_movej_follow:{args}")
def rm_get_current_arm_state(self):
print("get_current_arm_state")
return ACTION_SUCCESS, {"pose":[0.0,0.0,0.0,0.0,0.0,0.0],"joint":[0.0,0.0,0.0,0.0,0.0,0.0]}
def rm_movej_p(self,*args):
print(f"rm_movej_p:{args}")
def rm_set_joint_en_state(self,*args):
print(f"rm_set_joint_en_state:{args}")
def rm_set_gripper_route(self,*args):
print(f"rm_set_gripper_route:{args}")
def rm_set_gripper_position(self,*kargs):
print(f"rm_set_gripper_position:{kargs}")
def rm_get_gripper_state(self):
print("get_gripper_state")
return ACTION_SUCCESS, {"actpos":0.0}
def rm_set_gripper_release(self,*args):
print(f"rm_set_gripper_release:{args}")
def rm_set_gripper_pick_on(self,*args):
print(f"rm_set_gripper_pick_on:{args}")
def rm_movev_canfd(self,*args):
print(f"rm_movev_canfd:{args}")
def rm_destory(self):
print("destory")
class RealmanMotorsBus(MotorsBus): class RealmanMotorsBus(MotorsBus):
model_number_table={} model_number_table={}
@@ -68,14 +27,12 @@ class RealmanMotorsBus(MotorsBus):
motors:dict[str, Motor], motors:dict[str, Motor],
gripper_range:list[int], gripper_range:list[int],
joint: list, joint: list,
udp_ip: str,
udp_port: int,
mock: bool = False, mock: bool = False,
calibration: dict[str, MotorCalibration] | None = None, calibration: dict[str, MotorCalibration] | None = None,
): ):
super().__init__(port,motors, calibration) super().__init__(port,motors, calibration)
if mock:
self.rmarm = RoboticArmMock()
else:
self.rmarm = RoboticArm(rm_thread_mode_e.RM_TRIPLE_MODE_E)
address = port.split(':') address = port.split(':')
self.ip = address[0] self.ip = address[0]
self.port = int(address[1]) self.port = int(address[1])
@@ -83,8 +40,28 @@ class RealmanMotorsBus(MotorsBus):
self.gripper_range = gripper_range self.gripper_range = gripper_range
self.init_joint_position = joint self.init_joint_position = joint
self.safe_disable_position = joint self.safe_disable_position = joint
self.mock = mock
if mock:
#self.rmarm = RealmanMock()
self.rmarm = RoboticArm(rm_thread_mode_e.RM_DUAL_MODE_E)
else:
self.rmarm = RoboticArm(rm_thread_mode_e.RM_DUAL_MODE_E)
self.handle = None self.handle = None
self.init_pose = None self.init_pose = numpy.zeros(8)
self.init_pose[-2] = 1
self.running = False
custom = rm_udp_custom_config_t()
custom.joint_speed = 0
# custom.lift_state = 1
custom.hand_state = 1
custom.plus_state = 1
custom.plus_base=1
custom.expand_state = 1
custom.arm_current_status = 1
custom.expand_state = 1
self.udp_config = rm_realtime_push_config_t(1, True, udp_port, 0, udp_ip, custom)
self.lock = threading.Lock()
self.temp_pose = numpy.zeros(8)
@property @property
def motor_names(self) -> list[str]: def motor_names(self) -> list[str]:
@@ -97,12 +74,26 @@ class RealmanMotorsBus(MotorsBus):
@property @property
def motor_indices(self) -> list[int]: def motor_indices(self) -> list[int]:
return [idx for idx, _ in self.motors.values()] return [idx for idx, _ in self.motors.values()]
def update_arm_state(self, state:rm_realtime_arm_joint_state_t):
joint = list(state.joint_status.joint_position)
gripper = state.expandState.pos
pose = state.waypoint.position
euler = state.waypoint.euler
pose = [pose.x, pose.y, pose.z, euler.rx, euler.ry, euler.rz, 0]
self.current_arm_state = {"joint": joint, "gripper": gripper, "pose": pose}
def connect(self, enable=True) -> bool: def connect(self, enable=True) -> bool:
''' '''
使能机械臂并检测使能状态,尝试5s,如果使能超时则退出程序 使能机械臂并检测使能状态,尝试5s,如果使能超时则退出程序
''' '''
self.handle = self.rmarm.rm_create_robot_arm(self.ip, self.port)
if self.mock:
self.rmarm.rm_set_arm_run_mode(0)#仿真模式
else:
self.rmarm.rm_set_arm_run_mode(1)
enable_flag = False enable_flag = False
loop_flag = False loop_flag = False
# 设置超时时间(秒) # 设置超时时间(秒)
@@ -129,6 +120,7 @@ class RealmanMotorsBus(MotorsBus):
if(enable_flag == enable): if(enable_flag == enable):
loop_flag = True loop_flag = True
enable_flag = True enable_flag = True
break
else: else:
loop_flag = False loop_flag = False
enable_flag = False enable_flag = False
@@ -139,16 +131,34 @@ class RealmanMotorsBus(MotorsBus):
enable_flag = True enable_flag = True
break break
time.sleep(1) time.sleep(1)
# self.rmarm.rm_set_realtime_push(self.udp_config)
self.handle = self.rmarm.rm_create_robot_arm(self.ip, self.port) # self.arm_state_callback = rm_realtime_arm_state_callback_ptr(self.update_arm_state)
# self.rmarm.rm_realtime_arm_state_call_back(self.arm_state_callback)
self.rmarm.rm_movej(self.init_joint_position[:-1], 5, 0, 0, 1) self.rmarm.rm_movej(self.init_joint_position[:-1], 5, 0, 0, 1)
time.sleep(3) self.init_pose = self.getQuatPose()
ret = self.rmarm.rm_get_current_arm_state()
self.init_pose = ret[1]['pose']
resp = enable_flag resp = enable_flag
self.running = True
threading.Thread(target=self.update_pose).start()
threading.Thread(target=self.update_gripper).start()
print(f"Returning response: {resp}") print(f"Returning response: {resp}")
return resp return resp
def getQuatPose(self)->tuple[int,rm_current_arm_state_t]:
state = rm_current_arm_state_t()
ret = rm_get_current_arm_state(self.handle, byref(state))
return numpy.array([
state.pose.position.x,
state.pose.position.y,
state.pose.position.z,
state.pose.quaternion.w,
state.pose.quaternion.x,
state.pose.quaternion.y,
state.pose.quaternion.z,
self.rmarm.rm_get_gripper_state()[1]['actpos']
])
def read_pose(self):
return self.init_pose
def motor_names(self): def motor_names(self):
return return
@@ -170,9 +180,9 @@ class RealmanMotorsBus(MotorsBus):
return False return False
def write_arm(self, target_joint: list): def write_arm(self, target_joint: list):
ret = self.rmarm.rm_movej_follow(target_joint[:-1]) ret = self.rmarm.rm_movej(self.init_joint_position[:-1], 5, 0, 0, 1)
if ret != None: if ret != 0:
print("movej error:", ret[1]) print("movej error:", ret)
return ret return ret
ret = self.rmarm.rm_set_gripper_position(target_joint[-1], block=False, timeout=2) ret = self.rmarm.rm_set_gripper_position(target_joint[-1], block=False, timeout=2)
@@ -183,11 +193,7 @@ class RealmanMotorsBus(MotorsBus):
- 机械臂关节消息,单位1度;[-1, 1] - 机械臂关节消息,单位1度;[-1, 1]
- 机械臂夹爪消息,[-1, 1] - 机械臂夹爪消息,[-1, 1]
""" """
joint_msg = self.rmarm.rm_get_current_arm_state()[1] joint_state = self.read_pose()
joint_state = joint_msg['joint']
gripper_msg = self.rmarm.rm_get_gripper_state()[1]
gripper_state = gripper_msg['actpos']
return { return {
"joint_1": joint_state[0]/180, "joint_1": joint_state[0]/180,
@@ -196,15 +202,9 @@ class RealmanMotorsBus(MotorsBus):
"joint_4": joint_state[3]/180, "joint_4": joint_state[3]/180,
"joint_5": joint_state[4]/180, "joint_5": joint_state[4]/180,
"joint_6": joint_state[5]/180, "joint_6": joint_state[5]/180,
"gripper": (gripper_state-500)/500 "gripper": (joint_state[6]-500)/500
} }
5
def read_current_arm_joint_state(self):
return self.rmarm.rm_get_current_arm_state()[1]['joint']
def read_current_arm_endpose_state(self):
return self.rmarm.rm_get_current_arm_state()[1]['pose']
def disconnect(self, disable_torque = True): def disconnect(self, disable_torque = True):
self.safe_disconnect() self.safe_disconnect()
@@ -213,8 +213,8 @@ class RealmanMotorsBus(MotorsBus):
Move to safe disconnect position Move to safe disconnect position
""" """
self.write_arm(target_joint=self.safe_disable_position) self.write_arm(target_joint=self.safe_disable_position)
self.running = False
# 断开所有连接,销毁线程 # 断开所有连接,销毁线程
RoboticArm.rm_destory()
""" """
向机械臂写入动作 向机械臂写入动作
@@ -223,37 +223,40 @@ class RealmanMotorsBus(MotorsBus):
if name =="Goal_Position": if name =="Goal_Position":
self.write_arm(target_joint=actionData) self.write_arm(target_joint=actionData)
elif name == "Goal_Velocity":#速度透传模式 elif name == "Goal_Velocity":#速度透传模式
self.rmarm.rm_movev_canfd(list(actionData.values())[:6]) values = numpy.array(list(actionData.values()))
gripper = actionData['gripper'] with self.lock:
if gripper > 0 : self.temp_pose += numpy.array([*values[:6],0,values[-1]])
self.rmarm.rm_set_gripper_release(gripper*1000, False) def update_pose(self):
while self.running:
with self.lock:
self.temp_pose[-1] = self.temp_pose[-1]*1000
temp = self.init_pose + self.temp_pose
newr = R.from_rotvec(self.temp_pose[3:6].tolist())
oldr = R.from_quat(self.init_pose[3:7].tolist())
temp[3:7] = (oldr * newr).as_quat()
self.temp_pose.fill(0)
ret = self.rmarm.rm_movep_canfd(temp[:-1].tolist(), False)
if ret == 0:
self.init_pose = temp
else: else:
self.rmarm.rm_set_gripper_pick_on(gripper*1000, gripper*1000, False) print(f"Error: {ret}")
time.sleep(0.01)
def clamp(self,value, min_value, max_value):
return max(min(value, max_value), min_value)
def update_gripper(self):
while self.running:
if self.init_pose[-1]>0:
self.rmarm.rm_set_gripper_release(500,False,0)
self.init_pose[-1] = 0
elif self.init_pose[-1]<0:
self.rmarm.rm_set_gripper_pick(500,300,False,0)
self.init_pose[-1] = 0
def sync_read(self, data_name, motors = None, *, normalize = True, num_retry = 0): def sync_read(self, data_name, motors = None, *, normalize = True, num_retry = 0):
if data_name == "Present_Position": if data_name == "Present_Position":
return self.read() return self.read()
def _assert_protocol_is_compatible(self, instruction_name):
return True
"""
配置电机
"""
def configure_motors(self, return_delay_time=0, maximum_acceleration=254, acceleration=254) -> None:
self.rmarm.rm_set_gripper_route(self.gripper_range[0],self.gripper_range[1])
def disable_torque(self, motors: int | str | list[str] | None = None, num_retry: int = 0):
for motor in self._get_motors_list(motors):
self.rmarm.rm_set_joint_en_state(motor,0)
def _disable_torque(self, motor: int, model: str, num_retry: int = 0):
self.rmarm.rm_set_joint_en_state(motor,0)
def enable_torque(self, motors = None, num_retry = 0):
for motor in self._get_motors_list(motors):
self.rmarm.rm_set_joint_en_state(motor,1)
@property @property
def is_connected(self) -> bool: def is_connected(self) -> bool:
return self.handle is not None return self.handle is not None
@@ -265,62 +268,39 @@ class RealmanMotorsBus(MotorsBus):
pass pass
def _get_half_turn_homings(self, positions): def _get_half_turn_homings(self, positions):
offsets = {} pass
for motor_id, current_pos in positions.items():
# 确保输入是角度值
current_deg = self._ensure_angle_degrees(current_pos, motor_id)
# 核心逻辑让当前位置变成180°
offset = self._calculate_angle_offset(current_deg, motor_id)
offsets[motor_id] = offset
return offsets
def _calculate_angle_offset(self, current_deg, motor_id):
"""计算角度偏移量"""
# 获取关节角度范围从配置或SDK
# min_angle, max_angle = self._get_joint_limits(motor_id)
# 对于单圈关节,我们想要的目标是范围中点
# 但set_half_turn_homings的语义是"变成半圈(180°)"
TARGET = 180.0 # 固定目标180°
# 计算基本偏移
offset = TARGET - current_deg
# 单圈关节处理:偏移应该在[-180, 180)范围内
if motor_id <= 6: # 单圈关节
# 优化偏移到最短路径
while offset >= 180.0:
offset -= 360.0
while offset < -180.0:
offset += 360.0
else: # 多圈关节关节7
# 多圈关节:只需要考虑在当前圈内的偏移
current_in_first_turn = current_deg % 360.0
offset = TARGET - current_in_first_turn
# 同样优化到最短路径
if offset >= 180.0:
offset -= 360.0
elif offset < -180.0:
offset += 360.0
# 保留RealMan精度
return round(offset, 3)
def _find_single_motor(self, motor: str, initial_baudrate: int | None = None) -> tuple[int, int]: def _find_single_motor(self, motor: str, initial_baudrate: int | None = None) -> tuple[int, int]:
return 0,self.motors[motor].id return 0,self.motors[motor].id
def _encode_sign(self, data_name, ids_values): def _encode_sign(self, data_name, ids_values):
raise NotImplementedError pass
def _decode_sign(self, data_name, ids_values): def _decode_sign(self, data_name, ids_values):
raise NotImplementedError pass
def _split_into_byte_chunks(self, value, length): def _split_into_byte_chunks(self, value, length):
raise NotImplementedError pass
def broadcast_ping(self, num_retry = 0, raise_on_error = False): def broadcast_ping(self, num_retry = 0, raise_on_error = False):
raise NotImplementedError pass
def _handshake(self) -> None: def _handshake(self) -> None:
pass pass
def _assert_protocol_is_compatible(self, instruction_name):
return True
"""
配置电机
"""
def configure_motors(self, return_delay_time=0, maximum_acceleration=254, acceleration=254) -> None:
pass
def disable_torque(self, motors: int | str | list[str] | None = None, num_retry: int = 0):
pass
def _disable_torque(self, motor: int, model: str, num_retry: int = 0):
pass
def enable_torque(self, motors = None, num_retry = 0):
pass

View File

@@ -21,6 +21,8 @@ class RealmanRobot(Robot):
motors=config.motors, motors=config.motors,
joint=config.joint, joint=config.joint,
mock=self.config.mock, mock=self.config.mock,
udp_ip=self.config.udp_ip,
udp_port=self.config.udp_port,
gripper_range=config.gripper_range, gripper_range=config.gripper_range,
calibration=self.calibration, calibration=self.calibration,
) )
@@ -68,7 +70,7 @@ class RealmanRobot(Robot):
"Mismatch between calibration values in the motor and the calibration file or no calibration file found" "Mismatch between calibration values in the motor and the calibration file or no calibration file found"
) )
self.calibrate() self.calibrate()
self.configure() # self.configure()
logger.info(f"{self} connected.") logger.info(f"{self} connected.")
@property @property

View File

@@ -0,0 +1,29 @@
class RealmanMock:
def __init__(self):
self.joint = [0.0]*6
self.pose = [0.0]*6
self.gripper = 0
pass
def rm_create_robot_arm(self, ip: str, port: int, level: int = 3, log_func = None) -> int:
return 1
def rm_movej(self, joint: list[float], v: int, r: int, connect: int, block: int) -> int:
self.joint = joint
def rm_get_current_arm_state(self) -> tuple[int, dict[str, any]]:
return (0, {"joint": self.joint, "pose": self.pose})
def rm_get_gripper_state(self) -> tuple[int, dict[str, any]]:
return (0, {"actpos": self.gripper})
def rm_movep_canfd(self, pose: list[float], follow: bool, trajectory_mode: int = 0, radio: int = 0) -> int:
self.pose = pose
return 0
def rm_set_gripper_position(self, position: int, block: bool, timeout: int) -> int:
self.gripper = position
return 0
def rm_movej(self, joint: list[float], v: int, r: int, connect: int, block: int) -> int:
self.joint = joint
return 0
def rm_set_arm_run_mode(self, mode: int) ->int:
return 0

View File

@@ -9,15 +9,18 @@ class FlightStick(Xbox):
name = "flight_stick" name = "flight_stick"
def get_action(self): def get_action(self):
pygame.event.pump() pose_speeds = {}
pose_speeds = [0.0] * 6
"""更新末端位姿控制""" """更新末端位姿控制"""
# 根据控制模式调整步长 # 根据控制模式调整步长
current_linear_step = self.linear_step * (0.1 if self.fine_control_mode else 1.0) current_linear_step = self.linear_step * (0.1 if self.fine_control_mode else 1.0)
current_angular_step = self.angular_step * (0.1 if self.fine_control_mode else 1.0) current_angular_step = self.angular_step * (0.1 if self.fine_control_mode else 1.0)
if self.joystick.get_button(2): # A按钮
self.fine_control_mode = True
if self.joystick.get_button(3): # B按钮
self.fine_control_mode = False
# print(f"步长设置 - 线性: {current_linear_step}, 角度: {current_angular_step}") # print(f"步长设置 - 线性: {current_linear_step}, 角度: {current_angular_step}")
print(f"精细控制模式: {self.fine_control_mode}") # print(f"精细控制模式: {self.fine_control_mode}")
# print(f"{self.joystick.get_axis(0)},{self.joystick.get_axis(1)},{self.joystick.get_axis(2)},{self.joystick.get_axis(3)}") # print(f"{self.joystick.get_axis(0)},{self.joystick.get_axis(1)},{self.joystick.get_axis(2)},{self.joystick.get_axis(3)}")
# 方向键控制XY # 方向键控制XY
hat = self.joystick.get_hat(0) hat = self.joystick.get_hat(0)
@@ -26,36 +29,40 @@ class FlightStick(Xbox):
hat_left = hat[0] == -1 # X- hat_left = hat[0] == -1 # X-
hat_right = hat[0] == 1 # X+ hat_right = hat[0] == 1 # X+
# 计算各轴速度 # 计算各轴速度
pose_speeds['x.vel'] = -current_linear_step if hat_left else (current_linear_step if hat_right else 0.0) # X pose_speeds['x.vel'] = current_linear_step if hat_left else (-current_linear_step if hat_right else 0.0) # X
pose_speeds['y.vel'] = current_linear_step if hat_up else (-current_linear_step if hat_down else 0.0) # Y pose_speeds['y.vel'] = -current_linear_step if hat_up else (current_linear_step if hat_down else 0.0) # Y
# print(f"方向键状态: up={hat_up}, down={hat_down}, left={hat_left}, right={hat_right}") # print(f"方向键状态: up={hat_up}, down={hat_down}, left={hat_left}, right={hat_right}")
# 油门控制Z轴 if self.joystick.get_button(8): # X按钮
gas_axis = -self.joystick.get_axis(2) pose_speeds['z.vel'] = current_linear_step/3
elif self.joystick.get_button(9): # Y按钮
# 设置Z速度 pose_speeds['z.vel'] = -current_linear_step/3
z_mapping = self.apply_nonlinear_mapping(gas_axis) else:
# print(f"Z轴非线性映射: {gas_axis} -> {z_mapping}") pose_speeds['z.vel'] = 0
pose_speeds['z.vel'] = z_mapping * current_linear_step # Z
# 主摇杆X轴控制RX旋转 # 主摇杆X轴控制RX旋转
# 设置RX旋转速度 # 设置RX旋转速度
rx_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(1)) rx_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(0))
# print(f"RX轴非线性映射: {x_axis} -> {rx_mapping}") # print(f"RX轴非线性映射: {x_axis} -> {rx_mapping}")
pose_speeds['rx.vel'] = rx_mapping * current_angular_step * 2 # RX pose_speeds['rx.vel'] = rx_mapping * current_angular_step * 2 # RX
# 主摇杆Y轴控制RY旋转 # 主摇杆Y轴控制RY旋转
# 设置RY旋转速度 # 设置RY旋转速度
ry_mapping = -self.apply_nonlinear_mapping(-self.joystick.get_axis(0)) ry_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(1))
# print(f"RY轴非线性映射: {y_axis} -> {ry_mapping}") # print(f"RY轴非线性映射: {y_axis} -> {ry_mapping}")
pose_speeds['ry.vel'] = ry_mapping * current_angular_step * 2 # RY pose_speeds['ry.vel'] = ry_mapping * current_angular_step * 2 # RY
# 主摇杆左右旋转轴 控制RZ旋转 # 主摇杆左右旋转轴 控制RZ旋转
# 设置RZ旋转速度 # 设置RZ旋转速度
rz_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(3)) rz_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(3))
# print(f"RZ轴非线性映射: {z_axis} -> {rz_mapping}") # print(f"RZ轴非线性映射: {z_axis} -> {rz_mapping}")
pose_speeds['rz.vel'] = rz_mapping * current_angular_step * 2 # RZ pose_speeds['rz.vel'] = rz_mapping * current_angular_step * 2 # RZ
if self.joystick.get_button(0): # X按钮
pose_speeds['gripper.vel'] = 0 pose_speeds['gripper.vel'] = current_linear_step
elif self.joystick.get_button(1): # Y按钮
pose_speeds['gripper.vel'] = -current_linear_step
else:
pose_speeds['gripper.vel'] = 0
# print(f"pose_speeds: {pose_speeds}")
return pose_speeds return pose_speeds

View File

@@ -0,0 +1,2 @@
from .mix import Mix,MixConfig
__all__ = ["Mix", "MixConfig"]

View File

@@ -0,0 +1,6 @@
from dataclasses import dataclass, field
from lerobot.teleoperators import TeleoperatorConfig
@dataclass
@TeleoperatorConfig.register_subclass("mix")
class MixConfig(TeleoperatorConfig):
teleopList: dict[str,TeleoperatorConfig] = field(default_factory=dict[str,TeleoperatorConfig])

View File

@@ -0,0 +1,64 @@
import queue
import threading
import pygame
import time
import sys
from lerobot.teleoperators import Teleoperator,make_teleoperator_from_config
from .config import MixConfig
"""
混合控制器。
"""
class Mix(Teleoperator):
config_class = MixConfig
name = "mix"
def __init__(self, config: MixConfig):
self.config = config
self.teleopList = {}
for name,teleop in self.config.teleopList.items():
self.teleopList[name] = make_teleoperator_from_config(teleop)
@property
def action_features(self):
action_features = {}
for name,teleop in self.teleopList.items():
for i,item in enumerate(teleop.action_features()["names"].keys()):
action_features[f"{name}.{item}"] = i
return {
"dtype": "float32",
"shape": (len(action_features),),
"names": action_features,
}
@property
def feedback_features(self):
return {}
@property
def is_connected(self):
return all([teleop.is_connected for teleop in self.teleopList.values()])
def connect(self, calibrate = True):
for teleop in self.teleopList.values():
teleop.connect(calibrate)
@property
def is_calibrated(self):
return True
def calibrate(self):
return all([teleop.calibrate() for teleop in self.teleopList.values()])
def configure(self):
pass
def get_action(self):
data = {}
for index,teleop in self.teleopList.items():
for key,item in teleop.get_action().items():
data[f"{index}.{key}"] = item
return data
def send_feedback(self, feedback):
pass
def disconnect(self):
for teleop in self.teleopList.values():
teleop.disconnect()

View File

@@ -1,8 +1,11 @@
import queue
import threading
import pygame import pygame
import time import time
import sys import sys
from lerobot.teleoperators import Teleoperator from lerobot.teleoperators import Teleoperator
from .config import XboxConfig from .config import XboxConfig
from ...utlis.pygame_event import PygameEvent
""" """
Xbox类用于检测和监控飞行手柄。 Xbox类用于检测和监控飞行手柄。
""" """
@@ -21,6 +24,8 @@ class Xbox(Teleoperator):
self.fine_control_mode = False self.fine_control_mode = False
self.reset() self.reset()
def reset(self): def reset(self):
self.running = False
self.action_data ={"x.vel":0, "y.vel":0, "z.vel":0, "rx.vel.vel":0, "ry.vel":0, "rz.vel":0, "gripper.vel":0}
self.joystick = None self.joystick = None
@property @property
def action_features(self): def action_features(self):
@@ -37,8 +42,8 @@ class Xbox(Teleoperator):
@property @property
def is_connected(self): def is_connected(self):
return self.joystick is not None return self.joystick is not None
def connect(self, calibrate = True): def update(self,q:queue.Queue):
# 初始化pygame # 初始化pygame
pygame.init() pygame.init()
pygame.joystick.init() pygame.joystick.init()
@@ -47,16 +52,23 @@ class Xbox(Teleoperator):
print(f"检测到 {joystick_count} 个手柄设备") print(f"检测到 {joystick_count} 个手柄设备")
if joystick_count == 0: if joystick_count == 0:
print("未检测到任何手柄设备!") q.put((False,"未检测到任何手柄设备!"))
return False return False
if joystick_count<self.config.index+1: if joystick_count<self.config.index+1:
print(f"未检测到配置中指定的索引设备!") q.put((False,"未检测到配置中指定的索引设备!"))
return False return False
# 初始化所有检测到的手柄 # 初始化所有检测到的手柄
self.joystick = pygame.joystick.Joystick(self.config.index) self.joystick = pygame.joystick.Joystick(self.config.index)
print(f"已连接设备:{self.joystick.get_name()}") q.put((True,f"已连接设备:{self.joystick.get_name()}"))
while self.running:
self.action_data = self.update_action()
pygame.joystick.quit()
pygame.quit()
def connect(self, calibrate = True):
PygameEvent.start()
self.joystick = PygameEvent.getState(self.config.index)
@property @property
def is_calibrated(self): def is_calibrated(self):
return True return True
@@ -68,7 +80,6 @@ class Xbox(Teleoperator):
pass pass
def get_action(self): def get_action(self):
pygame.event.pump()
pose_speeds = {} pose_speeds = {}
"""更新末端位姿控制""" """更新末端位姿控制"""
# 根据控制模式调整步长 # 根据控制模式调整步长
@@ -80,7 +91,7 @@ class Xbox(Teleoperator):
self.fine_control_mode = False self.fine_control_mode = False
# print(f"步长设置 - 线性: {current_linear_step}, 角度: {current_angular_step}") # print(f"步长设置 - 线性: {current_linear_step}, 角度: {current_angular_step}")
print(f"精细控制模式: {self.fine_control_mode}") # print(f"精细控制模式: {self.fine_control_mode}")
# 方向键控制XY # 方向键控制XY
hat = self.joystick.get_hat(0) hat = self.joystick.get_hat(0)
@@ -90,42 +101,96 @@ class Xbox(Teleoperator):
hat_right = hat[0] == 1 # X+ hat_right = hat[0] == 1 # X+
# print(f"方向键状态: up={hat_up}, down={hat_down}, left={hat_left}, right={hat_right}") # print(f"方向键状态: up={hat_up}, down={hat_down}, left={hat_left}, right={hat_right}")
# 计算各轴速度 # 计算各轴速度
pose_speeds['x.vel'] = -current_linear_step if hat_left else (current_linear_step if hat_right else 0.0) # X pose_speeds['x.vel'] = current_linear_step if hat_left else (-current_linear_step if hat_right else 0.0) # X
pose_speeds['y.vel'] = current_linear_step if hat_up else (-current_linear_step if hat_down else 0.0) # Y pose_speeds['y.vel'] = -current_linear_step if hat_up else (current_linear_step if hat_down else 0.0) # Y
# 左摇杆X # 左右扳机控制z
z_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(1)) right_tiger = ((self.joystick.get_axis(5)+1)/2)
print(f"Z轴非线性映射: {self.joystick.get_axis(1)} -> {z_mapping}") left_tiger = ((self.joystick.get_axis(2)+1)/2)
pose_speeds['z.vel'] = z_mapping * current_angular_step * 2 # RY z_mapping = self.apply_nonlinear_mapping(left_tiger - right_tiger)
pose_speeds['z.vel'] = z_mapping * current_linear_step
#摇杆X轴控制RX旋转 #摇杆X轴控制RX旋转
# 设置RX旋转速度 # 设置RX旋转速度
rx_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(2)) rx_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(3))
# print(f"RX轴非线性映射: {x_axis} -> {rx_mapping}") # print(f"RX轴非线性映射: {x_axis} -> {rx_mapping}")
pose_speeds['rx.vel'] = rx_mapping * current_angular_step * 2 # RX pose_speeds['rx.vel'] = rx_mapping * current_angular_step * 2 # RX
# 摇杆Y轴控制RY旋转 # 摇杆Y轴控制RY旋转
# 设置RY旋转速度 # 设置RY旋转速度
ry_mapping = -self.apply_nonlinear_mapping(-self.joystick.get_axis(3)) ry_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(4))
# print(f"RY轴非线性映射: {y_axis} -> {ry_mapping}") # print(f"RY轴非线性映射: {y_axis} -> {ry_mapping}")
pose_speeds['ry.vel'] = ry_mapping * current_angular_step * 2 # RY pose_speeds['ry.vel'] = ry_mapping * current_angular_step * 2 # RY
# 左右扳机控制RZ旋转 # 左摇杆X轴RZ旋转
# 设置RZ旋转速度 # 设置RZ旋转速度
right_tiger = ((self.joystick.get_axis(5)+1)/2) rz_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(0))
left_tiger = ((self.joystick.get_axis(4)+1)/2)
print(f"左右扳机: {left_tiger} {right_tiger}")
rz_mapping = self.apply_nonlinear_mapping(left_tiger - right_tiger)
# print(f"RZ轴非线性映射: {z_axis} -> {rz_mapping}") # print(f"RZ轴非线性映射: {z_axis} -> {rz_mapping}")
pose_speeds['rz.vel'] = rz_mapping * current_angular_step * 2 # RZ pose_speeds['rz.vel'] = rz_mapping * current_angular_step * 2 # RZ
# 摇杆Y轴控制夹爪 # 摇杆Y轴控制夹爪
# 设置夹爪开合速度 # 设置夹爪开合速度
gripper_mapping = -self.apply_nonlinear_mapping(-self.joystick.get_axis(0)) gripper_mapping = -self.apply_nonlinear_mapping(-self.joystick.get_axis(1))
# print(f"gripper轴非线性映射: {self.joystick.get_axis(0)} -> {gripper_mapping}") # print(f"gripper轴非线性映射: {self.joystick.get_axis(0)} -> {gripper_mapping}")
pose_speeds['gripper.vel'] = gripper_mapping * current_angular_step * 2 # RY pose_speeds['gripper.vel'] = gripper_mapping * current_angular_step * 2 # RY
return pose_speeds return pose_speeds
# def update_action(self):
# pygame.event.pump()
# pose_speeds = {}
# """更新末端位姿控制"""
# # 根据控制模式调整步长
# current_linear_step = self.linear_step * (0.1 if self.fine_control_mode else 1.0)
# current_angular_step = self.angular_step * (0.1 if self.fine_control_mode else 1.0)
# if self.joystick.get_button(0): # A按钮
# self.fine_control_mode = True
# if self.joystick.get_button(1): # B按钮
# self.fine_control_mode = False
# # print(f"步长设置 - 线性: {current_linear_step}, 角度: {current_angular_step}")
# # print(f"精细控制模式: {self.fine_control_mode}")
# # 方向键控制XY
# hat = self.joystick.get_hat(0)
# hat_up = hat[1] == 1 # Y+
# hat_down = hat[1] == -1 # Y-
# hat_left = hat[0] == -1 # X-
# hat_right = hat[0] == 1 # X+
# # print(f"方向键状态: up={hat_up}, down={hat_down}, left={hat_left}, right={hat_right}")
# # 计算各轴速度
# pose_speeds['x.vel'] = current_linear_step if hat_left else (-current_linear_step if hat_right else 0.0) # X
# pose_speeds['y.vel'] = -current_linear_step if hat_up else (current_linear_step if hat_down else 0.0) # Y
# # 左右扳机控制z轴
# right_tiger = ((self.joystick.get_axis(5)+1)/2)
# left_tiger = ((self.joystick.get_axis(2)+1)/2)
# z_mapping = self.apply_nonlinear_mapping(left_tiger - right_tiger)
# pose_speeds['z.vel'] = z_mapping * current_angular_step * 2
# #右摇杆X轴控制RX旋转
# # 设置RX旋转速度
# rx_mapping = self.apply_nonlinear_mapping(self.joystick.get_axis(3))
# # print(f"RX轴非线性映射: {x_axis} -> {rx_mapping}")
# pose_speeds['rx.vel'] = rx_mapping * current_angular_step * 2 # RX
# # 右摇杆Y轴控制RY旋转
# # 设置RY旋转速度
# ry_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(4))
# # print(f"RY轴非线性映射: {y_axis} -> {ry_mapping}")
# pose_speeds['ry.vel'] = ry_mapping * current_angular_step * 2 # RY
# # 左摇杆X轴RZ旋转
# # 设置RZ旋转速度
# rz_mapping = self.apply_nonlinear_mapping(-self.joystick.get_axis(0))
# # print(f"RZ轴非线性映射: {z_axis} -> {rz_mapping}")
# pose_speeds['rz.vel'] = rz_mapping * current_angular_step * 2 # RZ
# # 左摇杆Y轴控制夹爪
# # 设置夹爪开合速度
# gripper_mapping = -self.apply_nonlinear_mapping(-self.joystick.get_axis(1))
# # print(f"gripper轴非线性映射: {self.joystick.get_axis(0)} -> {gripper_mapping}")
# pose_speeds['gripper.vel'] = gripper_mapping * current_angular_step * 2 # RY
# return pose_speeds
def apply_nonlinear_mapping(self, value): def apply_nonlinear_mapping(self, value):
"""应用非线性映射以提高控制精度""" """应用非线性映射以提高控制精度"""
@@ -142,5 +207,3 @@ class Xbox(Teleoperator):
def disconnect(self): def disconnect(self):
self.reset() self.reset()
pygame.joystick.quit()
pygame.quit()

View File

@@ -0,0 +1,6 @@
import ctypes
import platform
if platform.system() == 'Linux':
ctypes.CDLL("/opt/apps/roboticsservice/SDK/x64/libPXREARobotSDK.so")
from .xr import Xr,XrConfig
__all__ = ["Xr", "XrConfig"]

View File

@@ -0,0 +1,6 @@
from dataclasses import dataclass
from lerobot.teleoperators import TeleoperatorConfig
@dataclass
@TeleoperatorConfig.register_subclass("xr")
class XrConfig(TeleoperatorConfig):
pass

View File

@@ -0,0 +1,213 @@
import threading
import numpy as np
import xrobotoolkit_sdk as xrt
import time
import sys
from lerobot.teleoperators import Teleoperator
from .config import XrConfig
from scipy.spatial.transform import Rotation as R
import meshcat.transformations as tf
"""
Xbox类用于检测和监控飞行手柄。
"""
class Xr(Teleoperator):
config_class = XrConfig
name = "xr"
def __init__(self, config: XrConfig):
self.R_HEADSET_TO_WORLD = np.array(
[
[-1, 0, 0],
[0, 0, 1],
[0, 1, 0],
]
)
self.R_HEADSET_TO_WORLD2 = np.array(
[
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
]
)
self.config = config
# 控制参数
self.linear_step = 0.0015 # 线性移动步长(m)
self.current_linear_step = self.linear_step
self.angular_step = 0.0003 # 角度步长(rad) - 从度转换为弧度
self.current_angular_step = self.angular_step
# 摇杆死区
self.deadzone = 0.15
# 精细控制模式
self.fine_control_mode = False
self.running = False
self.data = {
"left": {
"pose": np.zeros(7),
"init_pose":None,
"trigger":0.0,
"axis":[0.0]*2,
"grip":0.0,
"axis_button":0.0
},
"right": {
"pose": np.zeros(7),
"init_pose":None,
"trigger":0.0,
"grip":0.0,
"axis":[0.0]*2,
"axis_button":0.0
}
}
self.scale_factor = 0.2
self.x = 0.0
self.y = 0.0
self.a = 0.0
self.b = 0.0
@property
def action_features(self):
return {
"dtype": "float32",
"shape": (7,),
"names": {"x.vel":0, "y.vel":1, "z.vel":2, "rx.vel.vel":3, "ry.vel":4, "rz.vel":5, "rw.vel":6, "gripper.vel":7},
}
@property
def feedback_features(self):
return {}
@property
def is_connected(self):
return self.joystick is not None
def quaternion2euler(self,quaternion:list):
r = R.from_quat(quaternion)
euler = r.as_euler('xyz', degrees=True)
return euler
def update(self):
while self.running:
self.a = xrt.get_A_button()
self.b = xrt.get_B_button()
self.x = xrt.get_X_button()
self.y = xrt.get_Y_button()
self.data['left']['pose'] = xrt.get_left_controller_pose()
self.data['left']['trigger'] = xrt.get_left_trigger()
self.data['left']['grip'] = xrt.get_left_grip()
self.data['left']['axis'] = xrt.get_left_axis()
self.data['left']['axis_button'] = xrt.get_left_axis_click()
self.data['right']['pose'] = xrt.get_right_controller_pose()
self.data['right']['trigger'] = xrt.get_right_trigger()
self.data['right']['grip'] = xrt.get_right_grip()
self.data['right']['axis'] = xrt.get_right_axis()
self.data['right']['axis_button'] = xrt.get_right_axis_click()
time.sleep(0.01)
def connect(self, calibrate = True):
# 初始化vr
xrt.init()
# 设置超时时间(秒)
timeout = 5
# 记录进入循环前的时间
start_time = time.time()
elapsed_time_flag = False
print("等待vr初始化完成")
while True:
elapsed_time = time.time() - start_time
right_pose = xrt.get_right_controller_pose()
left_pose = xrt.get_left_controller_pose()
if not all(num == 0 for num in right_pose) and not all(num == 0 for num in left_pose):
print(f"connect success")
self.running = True
threading.Thread(target=self.update).start()
break
# 检查是否超过超时时间
if elapsed_time > timeout:
print("超时....")
elapsed_time_flag = True
break
time.sleep(1)
return not elapsed_time_flag
@property
def is_calibrated(self):
return True
def calibrate(self):
pass
def configure(self):
pass
def get_pose(self, prefix,pose_speeds):
data = self.data[prefix]
xr_pose = np.array(data['pose'])
"""Process the current XR controller pose."""
# Get position and orientation
controller_xyz = np.array([xr_pose[0], xr_pose[1], xr_pose[2]])
controller_xyz = self.R_HEADSET_TO_WORLD @ controller_xyz
controller_quat = R.from_quat(xr_pose[3:])
if data['trigger'] >0 or data['grip']>0:
isLock = data['grip']>0
if data['init_pose'] is None:
data['init_pose'] = controller_quat
data['init_position'] = controller_xyz
else:
data['init_pose'] = None
if data['init_pose'] is None:
delta_xyz = np.zeros(3)
delta_rot = np.array([0.0, 0.0, 0.0])
else:
delta_xyz = (controller_xyz - data['init_position']) * self.scale_factor
delta_rot = self.quat_diff_as_angle_axis(controller_quat,data['init_pose'])
data['init_pose'] = controller_quat
data['init_position'] = controller_xyz
if isLock :
delta_rot = [0.0,0.0,0.0]
else:
delta_rot *= self.scale_factor
delta_rot = self.R_HEADSET_TO_WORLD2 @ delta_rot
print(f"{prefix}:{delta_rot}")
pose_speeds[f'{prefix}.x.vel'] = delta_xyz[0]
pose_speeds[f'{prefix}.y.vel'] = delta_xyz[1]
pose_speeds[f'{prefix}.z.vel'] = delta_xyz[2]
pose_speeds[f'{prefix}.rx.vel'] = delta_rot[2]
pose_speeds[f'{prefix}.ry.vel'] = delta_rot[1]
pose_speeds[f'{prefix}.rz.vel'] = -delta_rot[0]
# 设置夹爪开合速度
gripper_mapping = -self.apply_nonlinear_mapping(-data['axis'][0])
pose_speeds[f'{prefix}.gripper.vel'] = gripper_mapping * self.current_angular_step * 2
def quat_diff_as_angle_axis(self,q1: R, q2: R, eps: float = 1e-6) -> np.ndarray:
delta_q = q2 * q1.inv()
rotvec = delta_q.as_rotvec()
angle = np.linalg.norm(rotvec)
if angle < eps:
return np.zeros(3, dtype=np.float64)
return rotvec
def get_action(self):
pose_speeds = {}
"""更新末端位姿控制"""
# 根据控制模式调整步长
if self.a: # A按钮
self.fine_control_mode = True
self.scale_factor = 0.07
if self.b: # B按钮
self.fine_control_mode = False
self.scale_factor = 0.2
self.get_pose('left',pose_speeds)
self.get_pose('right',pose_speeds)
return pose_speeds
def apply_nonlinear_mapping(self, value):
"""应用非线性映射以提高控制精度"""
# 保持符号,但对数值应用平方映射以提高精度
value = 0.0 if abs(value) < self.deadzone else value
sign = 1 if value >= 0 else -1
return sign * (abs(value) ** 2)
def send_feedback(self, feedback):
pass
def disconnect(self):
self.running = False

View File

@@ -0,0 +1,81 @@
import threading
import pygame
import atexit
class PygameEventState(object):
def __init__(self,joystick):
joystick.init()
self.states={
'axis':[0]*joystick.get_numaxes(),
'button':[0]*joystick.get_numbuttons(),
'hat':[[0,0]]*joystick.get_numhats()
}
def get_axis(self,index):
return self.states['axis'][index]
def get_numaxes(self):
return len(self.states['axis'])
def set_axis(self,index,value):
self.states['axis'][index]=value
def get_button(self,index):
return self.states['button'][index]
def get_numbuttons(self):
return len(self.states['button'])
def set_button(self,index,value):
self.states['button'][index]=value
def get_hat(self,index):
return self.states['hat'][index]
def get_numhats(self):
return len(self.states['hat'])
def set_hat(self,index,value):
self.states['hat'][index]=value
class _PygameEvent:
def __init__(self):
self.running = False
def start(self):
if self.running: return
self.running = True
threading.Thread(target=self.eventLoop).start()
def getState(self,index):
if index >= len(self.states):
raise ValueError("不存在的控制器")
return self.states[index]
def eventLoop(self):
# 初始化pygame
pygame.init()
pygame.joystick.init()
"""检测连接的手柄"""
joystick_count = pygame.joystick.get_count()
self.states=[]
joysticks = []
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
self.states.append(PygameEventState(joystick))
joysticks.append(joystick)
print(f"检测到 {joystick_count} 个手柄设备")
while self.running:
event = pygame.event.wait()
data = event.dict
if 'instance_id' not in data:
continue
state = self.states[data['instance_id']]
if event.type == pygame.JOYAXISMOTION:
state.set_axis(data['axis'], data['value'])
elif event.type == pygame.JOYHATMOTION:
state.set_hat(data['hat'], data['value'])
elif event.type == pygame.JOYBUTTONUP:
state.set_button(data['button'], 0)
elif event.type == pygame.JOYBUTTONDOWN:
state.set_button(data['button'], 1)
def stop(self):
self.running = False
@atexit.register
def exit():
PygameEvent.stop()
PygameEvent = _PygameEvent()

12
teleop.py Normal file
View File

@@ -0,0 +1,12 @@
import cProfile
import io
import pstats
from lerobot.scripts.lerobot_teleoperate import teleoperate
from robot_client.robots.realman import RealmanRobot,RealmanRobotConfig
from robot_client.robots.mix import MixRobot,MixRobotConfig
from robot_client.teleoperators.xbox import Xbox,XboxConfig
from robot_client.teleoperators.flight_stick import FlightStick,FlightStickConfig
from robot_client.teleoperators.xr import XrConfig
from robot_client.teleoperators.mix import Mix,MixConfig
if __name__ == "__main__":
teleoperate()

131
test.py Normal file
View File

@@ -0,0 +1,131 @@
import time
import numpy as np
from robot_client.teleoperators.xr import Xr,XrConfig
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy.spatial.transform import Rotation
from mpl_toolkits.mplot3d import Axes3D,art3d
import matplotlib.patches as mpatches
def create_cube(center=(0, 0, 0), size=1):
"""创建立方体的顶点和面"""
# 立方体的8个顶点
vertices = np.array([
[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]
], dtype=float)
# 缩放并平移
vertices = vertices * (size / 2)
vertices = vertices + np.array(center)
# 定义6个面的顶点索引
faces = [
[0, 1, 2, 3], # 底面
[4, 5, 6, 7], # 顶面
[0, 1, 5, 4], # 前面
[2, 3, 7, 6], # 后面
[1, 2, 6, 5], # 右面
[0, 3, 7, 4], # 左面
]
return vertices, faces
def apply_rotation_to_cube(vertices, quaternion):
"""将四元数旋转应用到立方体顶点"""
q_xyzw = quaternion
rot = R.from_quat(q_xyzw)
# 计算中心点
center = np.mean(vertices, axis=0)
# 相对中心的旋转
rotated_vertices = vertices.copy()
rotated_vertices -= center
rotated_vertices = rot.apply(rotated_vertices)
rotated_vertices += center
return rotated_vertices
def plot_rotating_cube(fig,quat):
# 创建立方体
vertices, faces = create_cube(center=(0, 0, 0), size=2)
# 颜色设置
face_colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b']
edge_color = 'black'
# 绘制每个四元数对应的旋转
# 应用旋转
rotated_vertices = apply_rotation_to_cube(vertices, quat)
# 绘制3D立方体
for j, face in enumerate(faces):
face_verts = rotated_vertices[face]
ax3d.add_collection3d(
art3d.Poly3DCollection(
[face_verts],
facecolors=face_colors[j % len(face_colors)],
alpha=0.6,
edgecolors=edge_color,
linewidths=1
)
)
# 绘制坐标轴
axis_length = 3
axes = np.array([[axis_length, 0, 0], [0, axis_length, 0], [0, 0, axis_length]])
rot = R.from_quat(quat if len(quat)==4 else [quat[1], quat[2], quat[3], quat[0]])
rotated_axes = rot.apply(axes)
colors = ['red', 'green', 'blue']
labels = ['X', 'Y', 'Z']
for axis, color, label in zip(rotated_axes, colors, labels):
ax3d.quiver(0, 0, 0, axis[0], axis[1], axis[2],
color=color, arrow_length_ratio=0.1, linewidth=2)
ax3d.text(axis[0], axis[1], axis[2], label, color=color, fontsize=12, fontweight='bold')
return ax3d
# 示例使用
if __name__ == "__main__":
# 创建一个旋转序列
from scipy.spatial.transform import Rotation as R
"""绘制立方体旋转序列"""
fig = plt.figure(figsize=(12, 8))
# 创建子图布局
ax3d = fig.add_subplot(121, projection='3d')
# 设置3D坐标轴
ax3d.set_xlim([-3, 3])
ax3d.set_ylim([-3, 3])
ax3d.set_zlim([-3, 3])
ax3d.set_xlabel('X轴', fontsize=10)
ax3d.set_ylabel('Y轴', fontsize=10)
ax3d.set_zlabel('Z轴', fontsize=10)
ax3d.set_title('旋转立方体', fontsize=12)
ax3d.view_init(elev=20, azim=45)
fig.suptitle('四元数旋转可视化', fontsize=16, fontweight='bold')
angle = 1
rot = R.from_euler('y', angle)
quat = rot.as_quat() # (x, y, z, w)
def update(frame):
return plot_rotating_cube(fig,ax3d,quat)
ani = FuncAnimation(fig, update, frames=200, blit=True)#blit是关键
plt.show()
xr = Xr(XrConfig())
xr.connect()
while True:
data = xr.get_action()
plot_rotating_cube([data["left.rx.vel"],data["left.ry.vel"],data["left.rz.vel"],data["left.rw.vel"]])
time.sleep(200)

24
test2.py Normal file
View File

@@ -0,0 +1,24 @@
from Robotic_Arm.rm_robot_interface import *
import numpy
def getPose(handle)->tuple[int,rm_current_arm_state_t]:
state = rm_current_arm_state_t()
ret = rm_get_current_arm_state(handle, byref(state))
return ret,state
# 运行简化版
if __name__ == "__main__":
rmarm = RoboticArm(rm_thread_mode_e.RM_DUAL_MODE_E)
handle = rmarm.rm_create_robot_arm("127.0.0.1", 8800)
rmarm.rm_set_arm_run_mode(0)
rmarm.rm_movej([15,90,10,80,110,0], 5, 0, 0, 1)
ret,pose = getPose(handle)
init_pose = numpy.array([
pose.pose.position.x,
pose.pose.position.y,
pose.pose.position.z,
pose.qu
])
init_pose[0]+=0.02
print(init_pose)
ret = rmarm.rm_movel(init_pose.tolist(),5,50,0,1)
print(ret)

632
uv.lock generated
View File

@@ -3,7 +3,8 @@ revision = 3
requires-python = ">=3.12" requires-python = ">=3.12"
resolution-markers = [ resolution-markers = [
"sys_platform == 'linux'", "sys_platform == 'linux'",
"sys_platform != 'linux'", "sys_platform == 'win32'",
"sys_platform != 'linux' and sys_platform != 'win32'",
] ]
[[package]] [[package]]
@@ -131,6 +132,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" },
] ]
[[package]]
name = "annotated-doc"
version = "0.0.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" },
]
[[package]] [[package]]
name = "annotated-types" name = "annotated-types"
version = "0.7.0" version = "0.7.0"
@@ -140,6 +150,28 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
] ]
[[package]]
name = "anyio"
version = "4.12.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "idna" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" },
]
[[package]]
name = "asttokens"
version = "3.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" },
]
[[package]] [[package]]
name = "attrs" name = "attrs"
version = "25.4.0" version = "25.4.0"
@@ -194,6 +226,63 @@ wheels = [
{ 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" }, { 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]]
name = "cffi"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
]
[[package]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"
version = "3.4.4" version = "3.4.4"
@@ -331,6 +420,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f4/c8/09012ac195a0aab58755800d2efdc0e7d5905053509f12cb5d136c911cda/datasets-4.1.1-py3-none-any.whl", hash = "sha256:62e4f6899a36be9ec74a7e759a6951253cc85b3fcfa0a759b0efa8353b149dac", size = 503623, upload-time = "2025-09-18T13:14:25.111Z" }, { url = "https://files.pythonhosted.org/packages/f4/c8/09012ac195a0aab58755800d2efdc0e7d5905053509f12cb5d136c911cda/datasets-4.1.1-py3-none-any.whl", hash = "sha256:62e4f6899a36be9ec74a7e759a6951253cc85b3fcfa0a759b0efa8353b149dac", size = 503623, upload-time = "2025-09-18T13:14:25.111Z" },
] ]
[[package]]
name = "decorator"
version = "5.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" },
]
[[package]] [[package]]
name = "deepdiff" name = "deepdiff"
version = "8.6.1" version = "8.6.1"
@@ -371,6 +469,17 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" },
] ]
[[package]]
name = "dotenv"
version = "0.9.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dotenv" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/b2/b7/545d2c10c1fc15e48653c91efde329a790f2eecfbbf2bd16003b5db2bab0/dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9", size = 1892, upload-time = "2025-02-19T22:15:01.647Z" },
]
[[package]] [[package]]
name = "draccus" name = "draccus"
version = "0.10.0" version = "0.10.0"
@@ -402,6 +511,15 @@ version = "1.9.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/63/fe/a17c106a1f4061ce83f04d14bcedcfb2c38c7793ea56bfb906a6fadae8cb/evdev-1.9.2.tar.gz", hash = "sha256:5d3278892ce1f92a74d6bf888cc8525d9f68af85dbe336c95d1c87fb8f423069", size = 33301, upload-time = "2025-05-01T19:53:47.69Z" } sdist = { url = "https://files.pythonhosted.org/packages/63/fe/a17c106a1f4061ce83f04d14bcedcfb2c38c7793ea56bfb906a6fadae8cb/evdev-1.9.2.tar.gz", hash = "sha256:5d3278892ce1f92a74d6bf888cc8525d9f68af85dbe336c95d1c87fb8f423069", size = 33301, upload-time = "2025-05-01T19:53:47.69Z" }
[[package]]
name = "executing"
version = "2.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" },
]
[[package]] [[package]]
name = "farama-notifications" name = "farama-notifications"
version = "0.0.4" version = "0.0.4"
@@ -411,6 +529,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/05/2c/ffc08c54c05cdce6fbed2aeebc46348dbe180c6d2c541c7af7ba0aa5f5f8/Farama_Notifications-0.0.4-py3-none-any.whl", hash = "sha256:14de931035a41961f7c056361dc7f980762a143d05791ef5794a751a2caf05ae", size = 2511, upload-time = "2023-02-27T18:28:39.447Z" }, { url = "https://files.pythonhosted.org/packages/05/2c/ffc08c54c05cdce6fbed2aeebc46348dbe180c6d2c541c7af7ba0aa5f5f8/Farama_Notifications-0.0.4-py3-none-any.whl", hash = "sha256:14de931035a41961f7c056361dc7f980762a143d05791ef5794a751a2caf05ae", size = 2511, upload-time = "2023-02-27T18:28:39.447Z" },
] ]
[[package]]
name = "fastapi"
version = "0.124.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-doc" },
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cd/21/ade3ff6745a82ea8ad88552b4139d27941549e4f19125879f848ac8f3c3d/fastapi-0.124.4.tar.gz", hash = "sha256:0e9422e8d6b797515f33f500309f6e1c98ee4e85563ba0f2debb282df6343763", size = 378460, upload-time = "2025-12-12T15:00:43.891Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3e/57/aa70121b5008f44031be645a61a7c4abc24e0e888ad3fc8fda916f4d188e/fastapi-0.124.4-py3-none-any.whl", hash = "sha256:6d1e703698443ccb89e50abe4893f3c84d9d6689c0cf1ca4fad6d3c15cf69f15", size = 113281, upload-time = "2025-12-12T15:00:42.44Z" },
]
[[package]] [[package]]
name = "filelock" name = "filelock"
version = "3.20.0" version = "3.20.0"
@@ -420,6 +553,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" },
] ]
[[package]]
name = "flameprof"
version = "0.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c0/e7/114f6710d31854b694598f577f9eac49d7f38b7fb8a55e86e2d3f848fd1c/flameprof-0.4.tar.gz", hash = "sha256:dbc86d4190cbbba624f1e0a40f44d9db96138e27534d83c8ef42d420857875a3", size = 7865, upload-time = "2018-12-25T09:28:48.554Z" }
[[package]] [[package]]
name = "frozenlist" name = "frozenlist"
version = "1.8.0" version = "1.8.0"
@@ -562,6 +701,15 @@ wheels = [
{ 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" }, { 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]]
name = "h11"
version = "0.16.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
]
[[package]] [[package]]
name = "hf-transfer" name = "hf-transfer"
version = "0.1.9" version = "0.1.9"
@@ -717,6 +865,51 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ce/ff/3b59672c47c6284e8005b42e84ceba13864aa0f39f067c973d1af02f5d91/InquirerPy-0.3.4-py3-none-any.whl", hash = "sha256:c65fdfbac1fa00e3ee4fb10679f4d3ed7a012abf4833910e63c295827fe2a7d4", size = 67677, upload-time = "2022-06-27T23:11:17.723Z" }, { url = "https://files.pythonhosted.org/packages/ce/ff/3b59672c47c6284e8005b42e84ceba13864aa0f39f067c973d1af02f5d91/InquirerPy-0.3.4-py3-none-any.whl", hash = "sha256:c65fdfbac1fa00e3ee4fb10679f4d3ed7a012abf4833910e63c295827fe2a7d4", size = 67677, upload-time = "2022-06-27T23:11:17.723Z" },
] ]
[[package]]
name = "ipython"
version = "9.8.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "decorator" },
{ name = "ipython-pygments-lexers" },
{ name = "jedi" },
{ name = "matplotlib-inline" },
{ name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
{ name = "prompt-toolkit" },
{ name = "pygments" },
{ name = "stack-data" },
{ name = "traitlets" },
]
sdist = { url = "https://files.pythonhosted.org/packages/12/51/a703c030f4928646d390b4971af4938a1b10c9dfce694f0d99a0bb073cb2/ipython-9.8.0.tar.gz", hash = "sha256:8e4ce129a627eb9dd221c41b1d2cdaed4ef7c9da8c17c63f6f578fe231141f83", size = 4424940, upload-time = "2025-12-03T10:18:24.353Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/df/8ee1c5dd1e3308b5d5b2f2dfea323bb2f3827da8d654abb6642051199049/ipython-9.8.0-py3-none-any.whl", hash = "sha256:ebe6d1d58d7d988fbf23ff8ff6d8e1622cfdb194daf4b7b73b792c4ec3b85385", size = 621374, upload-time = "2025-12-03T10:18:22.335Z" },
]
[[package]]
name = "ipython-pygments-lexers"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" },
]
[[package]]
name = "jedi"
version = "0.19.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "parso" },
]
sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" },
]
[[package]] [[package]]
name = "jinja2" name = "jinja2"
version = "3.1.6" version = "3.1.6"
@@ -838,6 +1031,18 @@ wheels = [
{ 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" }, { 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-inline"
version = "0.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "traitlets" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110, upload-time = "2025-10-23T09:00:22.126Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" },
]
[[package]] [[package]]
name = "mergedeep" name = "mergedeep"
version = "1.3.4" version = "1.3.4"
@@ -847,6 +1052,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" },
] ]
[[package]]
name = "meshcat"
version = "0.3.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ipython" },
{ name = "numpy" },
{ name = "pillow" },
{ name = "pyngrok" },
{ name = "pyzmq" },
{ name = "tornado" },
{ name = "u-msgpack-python" },
]
sdist = { url = "https://files.pythonhosted.org/packages/af/c2/fae203e8e2119d4c793c9d7d2b8d1fea10752bb39b7b330beb8e67b6117c/meshcat-0.3.2.tar.gz", hash = "sha256:2cfe17cde4fe85d072a3de018a9dabf5626f80c255fff2ce63b26a48d2484ad9", size = 611361, upload-time = "2021-11-07T20:31:55.305Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a8/c3/5f2b53fd7d43abb8c67015c737569303f39f43aa2b5a4c0add860be5d7e8/meshcat-0.3.2-py3-none-any.whl", hash = "sha256:cba0465d0e29658c48bb65d27f5c8e04ff0a1ac8ce916d65621146c06258a1c7", size = 2640524, upload-time = "2021-11-07T20:31:53.033Z" },
]
[[package]] [[package]]
name = "mpmath" name = "mpmath"
version = "1.3.0" version = "1.3.0"
@@ -1242,6 +1465,27 @@ wheels = [
{ 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" }, { 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]]
name = "parso"
version = "0.8.5"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" },
]
[[package]]
name = "pexpect"
version = "4.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ptyprocess", marker = "sys_platform != 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" },
]
[[package]] [[package]]
name = "pfzy" name = "pfzy"
version = "0.3.4" version = "0.3.4"
@@ -1466,6 +1710,24 @@ wheels = [
{ 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" }, { 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]]
name = "ptyprocess"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" },
]
[[package]]
name = "pure-eval"
version = "0.2.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" },
]
[[package]] [[package]]
name = "pyarrow" name = "pyarrow"
version = "22.0.0" version = "22.0.0"
@@ -1509,6 +1771,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" }, { url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" },
] ]
[[package]]
name = "pybind11"
version = "3.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/2f/7b/a6d8dcb83c457e24a9df1e4d8fd5fb8034d4bbc62f3c324681e8a9ba57c2/pybind11-3.0.1.tar.gz", hash = "sha256:9c0f40056a016da59bab516efb523089139fcc6f2ba7e4930854c61efb932051", size = 546914, upload-time = "2025-08-22T20:09:27.265Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cd/8a/37362fc2b949d5f733a8b0f2ff51ba423914cabefe69f1d1b6aab710f5fe/pybind11-3.0.1-py3-none-any.whl", hash = "sha256:aa8f0aa6e0a94d3b64adfc38f560f33f15e589be2175e103c0a33c6bce55ee89", size = 293611, upload-time = "2025-08-22T20:09:25.235Z" },
]
[[package]]
name = "pycparser"
version = "2.23"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" },
]
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "2.12.5" version = "2.12.5"
@@ -1617,6 +1897,27 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7e/11/17f7f319ca91824b86557e9303e3b7a71991ef17fd45286bf47d7f0a38e6/pygame-2.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a", size = 10620084, upload-time = "2024-09-29T11:48:51.587Z" }, { url = "https://files.pythonhosted.org/packages/7e/11/17f7f319ca91824b86557e9303e3b7a71991ef17fd45286bf47d7f0a38e6/pygame-2.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a", size = 10620084, upload-time = "2024-09-29T11:48:51.587Z" },
] ]
[[package]]
name = "pygments"
version = "2.19.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
]
[[package]]
name = "pyngrok"
version = "7.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyyaml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f6/7c/788a44567ffbad7c2d838e79a388ae5045520410f953c5097ad664d4763d/pyngrok-7.5.0.tar.gz", hash = "sha256:2fe91cba2c2531ecfb124b5071f377808b61a68a14ca3c99fcb7f3fdae05278f", size = 43149, upload-time = "2025-11-17T17:36:50.463Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bf/60/ab93dfb5721ba65f36bb6c2e07adfa21a8ac6525760b60f2ad6d31f7d098/pyngrok-7.5.0-py3-none-any.whl", hash = "sha256:1e50e71a59f1086f59e12e3d186f07ae2cbdccaf6f523678ef7ce3a180aba5c4", size = 24785, upload-time = "2025-11-17T17:36:49.372Z" },
]
[[package]] [[package]]
name = "pynput" name = "pynput"
version = "1.8.1" version = "1.8.1"
@@ -1651,10 +1952,10 @@ name = "pyobjc-framework-applicationservices"
version = "12.1" version = "12.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pyobjc-core", marker = "sys_platform != 'linux'" }, { name = "pyobjc-core", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-coretext", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-coretext", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-quartz", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-quartz", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" } sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" }
wheels = [ wheels = [
@@ -1670,7 +1971,7 @@ name = "pyobjc-framework-cocoa"
version = "12.1" version = "12.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pyobjc-core", marker = "sys_platform != 'linux'" }, { name = "pyobjc-core", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" } sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" }
wheels = [ wheels = [
@@ -1686,9 +1987,9 @@ name = "pyobjc-framework-coretext"
version = "12.1" version = "12.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pyobjc-core", marker = "sys_platform != 'linux'" }, { name = "pyobjc-core", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-quartz", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-quartz", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" } sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" }
wheels = [ wheels = [
@@ -1704,8 +2005,8 @@ name = "pyobjc-framework-quartz"
version = "12.1" version = "12.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pyobjc-core", marker = "sys_platform != 'linux'" }, { name = "pyobjc-core", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux'" }, { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" } sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" }
wheels = [ wheels = [
@@ -1716,6 +2017,17 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/a6/708a55f3ff7a18c403b30a29a11dccfed0410485a7548c60a4b6d4cc0676/pyobjc_framework_quartz-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0cc08fddb339b2760df60dea1057453557588908e42bdc62184b6396ce2d6e9a", size = 224580, upload-time = "2025-11-14T10:01:00.091Z" }, { url = "https://files.pythonhosted.org/packages/4d/a6/708a55f3ff7a18c403b30a29a11dccfed0410485a7548c60a4b6d4cc0676/pyobjc_framework_quartz-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0cc08fddb339b2760df60dea1057453557588908e42bdc62184b6396ce2d6e9a", size = 224580, upload-time = "2025-11-14T10:01:00.091Z" },
] ]
[[package]]
name = "pyrealsense2"
version = "2.56.5.9235"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fc/20/a46e60a496a17f1cf0cbdffb45e66dc015756e4dbce83580fd569e53e178/pyrealsense2-2.56.5.9235-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ba2c22981111adbefb169c39e023af4352a2409dfbff59f02c2404c68b82064b", size = 11062766, upload-time = "2025-07-28T14:59:26.551Z" },
{ url = "https://files.pythonhosted.org/packages/22/b5/dd8349abac780aed774f65825fc2ed3ca832b0ad2bf3293262bfa9a517b2/pyrealsense2-2.56.5.9235-cp312-cp312-win_amd64.whl", hash = "sha256:e9c64b94cf6170a3ad60416ff1bf969df8aafe383d4bff14e0fa10b2459d885b", size = 7801788, upload-time = "2025-07-28T14:59:28.303Z" },
{ url = "https://files.pythonhosted.org/packages/a8/66/fa706f1d906a06d5e7015d5b412a48de9914549792eb5cb53c1854e06427/pyrealsense2-2.56.5.9235-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:c203bc8c79d5958889681408f1038ee69b0021fd8cba7ff2d4532fc90295c4fc", size = 11062717, upload-time = "2025-07-28T14:59:30.072Z" },
{ url = "https://files.pythonhosted.org/packages/b2/88/19425ce6fa809d31a8d23f46dfa6aed9b16a881e8a00e0162d4b97ba1e64/pyrealsense2-2.56.5.9235-cp313-cp313-win_amd64.whl", hash = "sha256:ad8012f7fec843c3c6ec8904bfff048806dc7b4c7709e021c6ea75e83d8d5096", size = 7802471, upload-time = "2025-07-28T14:59:31.985Z" },
]
[[package]] [[package]]
name = "pyserial" name = "pyserial"
version = "3.5" version = "3.5"
@@ -1737,6 +2049,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
] ]
[[package]]
name = "python-dotenv"
version = "1.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" },
]
[[package]] [[package]]
name = "python-xlib" name = "python-xlib"
version = "0.33" version = "0.33"
@@ -1816,6 +2137,49 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d5/ca/6a2cc3a73170d10b5af1f1613baa2ed1f8f46f62dd0bfab2bffd2c2fe260/pyyaml_include-1.4.1-py3-none-any.whl", hash = "sha256:323c7f3a19c82fbc4d73abbaab7ef4f793e146a13383866831631b26ccc7fb00", size = 19079, upload-time = "2024-03-25T14:56:41.274Z" }, { url = "https://files.pythonhosted.org/packages/d5/ca/6a2cc3a73170d10b5af1f1613baa2ed1f8f46f62dd0bfab2bffd2c2fe260/pyyaml_include-1.4.1-py3-none-any.whl", hash = "sha256:323c7f3a19c82fbc4d73abbaab7ef4f793e146a13383866831631b26ccc7fb00", size = 19079, upload-time = "2024-03-25T14:56:41.274Z" },
] ]
[[package]]
name = "pyzmq"
version = "27.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "implementation_name == 'pypy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" },
{ url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" },
{ url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" },
{ url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" },
{ url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" },
{ url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" },
{ url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" },
{ url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" },
{ url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" },
{ url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" },
{ url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" },
{ url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" },
{ url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" },
{ url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" },
{ url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" },
{ url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" },
{ url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" },
{ url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" },
{ url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" },
{ url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" },
{ url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" },
{ url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" },
{ url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" },
{ url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" },
{ url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" },
{ url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" },
{ url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" },
{ url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" },
{ url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" },
{ url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" },
{ url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" },
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "2025.11.3" version = "2025.11.3"
@@ -1933,14 +2297,44 @@ name = "robot-client"
version = "0.1.0" version = "0.1.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "dotenv" },
{ name = "fastapi" },
{ name = "flameprof" },
{ name = "lerobot" }, { name = "lerobot" },
{ name = "meshcat" },
{ name = "pygame" }, { name = "pygame" },
{ name = "pyrealsense2" },
{ name = "robotic-arm" },
{ name = "scipy" },
{ name = "uvicorn" },
{ name = "websockets" },
{ name = "xrobotoolkit-sdk", version = "1.0.2", source = { path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-linux_x86_64.whl" }, marker = "sys_platform != 'win32'" },
{ name = "xrobotoolkit-sdk", version = "1.0.2", source = { path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-win_amd64.whl" }, marker = "sys_platform == 'win32'" },
] ]
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "dotenv", specifier = ">=0.9.9" },
{ name = "fastapi", specifier = ">=0.124.4" },
{ name = "flameprof", specifier = ">=0.4" },
{ name = "lerobot", specifier = ">=0.4.2" }, { name = "lerobot", specifier = ">=0.4.2" },
{ name = "meshcat", specifier = ">=0.3.2" },
{ name = "pygame", specifier = "==2.6.1" }, { name = "pygame", specifier = "==2.6.1" },
{ name = "pyrealsense2", specifier = ">=2.56.5.9235" },
{ name = "robotic-arm", specifier = "==1.1.3" },
{ name = "scipy", specifier = ">=1.16.3" },
{ name = "uvicorn", specifier = ">=0.38.0" },
{ name = "websockets", specifier = ">=15.0.1" },
{ name = "xrobotoolkit-sdk", marker = "sys_platform != 'win32'", path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-linux_x86_64.whl" },
{ name = "xrobotoolkit-sdk", marker = "sys_platform == 'win32'", path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-win_amd64.whl" },
]
[[package]]
name = "robotic-arm"
version = "1.1.3"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cd/8e/c5cf316ce8194d167ba8fe677a1e4eb01a0257b8eb9acad585a98467ffb5/robotic_arm-1.1.3-1-py3-none-any.whl", hash = "sha256:44a20394de93d8388995d2207f49670746bf2d074f7c4755891e85f06d1e4b8e", size = 2631470, upload-time = "2025-12-18T10:47:31.976Z" },
] ]
[[package]] [[package]]
@@ -1965,6 +2359,67 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" }, { url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" },
] ]
[[package]]
name = "scipy"
version = "1.16.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
]
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/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]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "2.47.0" version = "2.47.0"
@@ -2005,6 +2460,33 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" },
] ]
[[package]]
name = "stack-data"
version = "0.6.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "asttokens" },
{ name = "executing" },
{ name = "pure-eval" },
]
sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" },
]
[[package]]
name = "starlette"
version = "0.50.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" },
]
[[package]] [[package]]
name = "sympy" name = "sympy"
version = "1.14.0" version = "1.14.0"
@@ -2113,6 +2595,25 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/c0/131628e6d42682b0502c63fd7f647b8b5ca4bd94088f6c85ca7225db8ac4/torchvision-0.22.1-cp313-cp313t-win_amd64.whl", hash = "sha256:7414eeacfb941fa21acddcd725f1617da5630ec822e498660a4b864d7d998075", size = 1629892, upload-time = "2025-06-04T17:42:57.156Z" }, { url = "https://files.pythonhosted.org/packages/ab/c0/131628e6d42682b0502c63fd7f647b8b5ca4bd94088f6c85ca7225db8ac4/torchvision-0.22.1-cp313-cp313t-win_amd64.whl", hash = "sha256:7414eeacfb941fa21acddcd725f1617da5630ec822e498660a4b864d7d998075", size = 1629892, upload-time = "2025-06-04T17:42:57.156Z" },
] ]
[[package]]
name = "tornado"
version = "6.5.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/37/1d/0a336abf618272d53f62ebe274f712e213f5a03c0b2339575430b8362ef2/tornado-6.5.4.tar.gz", hash = "sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7", size = 513632, upload-time = "2025-12-15T19:21:03.836Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9", size = 443909, upload-time = "2025-12-15T19:20:48.382Z" },
{ url = "https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843", size = 442163, upload-time = "2025-12-15T19:20:49.791Z" },
{ url = "https://files.pythonhosted.org/packages/ba/b5/206f82d51e1bfa940ba366a8d2f83904b15942c45a78dd978b599870ab44/tornado-6.5.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17", size = 445746, upload-time = "2025-12-15T19:20:51.491Z" },
{ url = "https://files.pythonhosted.org/packages/8e/9d/1a3338e0bd30ada6ad4356c13a0a6c35fbc859063fa7eddb309183364ac1/tornado-6.5.4-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335", size = 445083, upload-time = "2025-12-15T19:20:52.778Z" },
{ url = "https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f", size = 445315, upload-time = "2025-12-15T19:20:53.996Z" },
{ url = "https://files.pythonhosted.org/packages/27/07/2273972f69ca63dbc139694a3fc4684edec3ea3f9efabf77ed32483b875c/tornado-6.5.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84", size = 446003, upload-time = "2025-12-15T19:20:56.101Z" },
{ url = "https://files.pythonhosted.org/packages/d1/83/41c52e47502bf7260044413b6770d1a48dda2f0246f95ee1384a3cd9c44a/tornado-6.5.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f", size = 445412, upload-time = "2025-12-15T19:20:57.398Z" },
{ url = "https://files.pythonhosted.org/packages/10/c7/bc96917f06cbee182d44735d4ecde9c432e25b84f4c2086143013e7b9e52/tornado-6.5.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8", size = 445392, upload-time = "2025-12-15T19:20:58.692Z" },
{ url = "https://files.pythonhosted.org/packages/0c/1a/d7592328d037d36f2d2462f4bc1fbb383eec9278bc786c1b111cbbd44cfa/tornado-6.5.4-cp39-abi3-win32.whl", hash = "sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1", size = 446481, upload-time = "2025-12-15T19:21:00.008Z" },
{ url = "https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl", hash = "sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc", size = 446886, upload-time = "2025-12-15T19:21:01.287Z" },
{ url = "https://files.pythonhosted.org/packages/50/49/8dc3fd90902f70084bd2cd059d576ddb4f8bb44c2c7c0e33a11422acb17e/tornado-6.5.4-cp39-abi3-win_arm64.whl", hash = "sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1", size = 445910, upload-time = "2025-12-15T19:21:02.571Z" },
]
[[package]] [[package]]
name = "tqdm" name = "tqdm"
version = "4.67.1" version = "4.67.1"
@@ -2125,6 +2626,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" },
] ]
[[package]]
name = "traitlets"
version = "5.14.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" },
]
[[package]] [[package]]
name = "triton" name = "triton"
version = "3.3.1" version = "3.3.1"
@@ -2181,6 +2691,15 @@ 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/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
] ]
[[package]]
name = "u-msgpack-python"
version = "2.8.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/36/9d/a40411a475e7d4838994b7f6bcc6bfca9acc5b119ce3a7503608c4428b49/u-msgpack-python-2.8.0.tar.gz", hash = "sha256:b801a83d6ed75e6df41e44518b4f2a9c221dc2da4bcd5380e3a0feda520bc61a", size = 18167, upload-time = "2023-05-18T09:28:12.187Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b1/5e/512aeb40fd819f4660d00f96f5c7371ee36fc8c6b605128c5ee59e0b28c6/u_msgpack_python-2.8.0-py2.py3-none-any.whl", hash = "sha256:1d853d33e78b72c4228a2025b4db28cda81214076e5b0422ed0ae1b1b2bb586a", size = 10590, upload-time = "2023-05-18T09:28:10.323Z" },
]
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.5.0" version = "2.5.0"
@@ -2190,6 +2709,19 @@ 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/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
] ]
[[package]]
name = "uvicorn"
version = "0.38.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" },
]
[[package]] [[package]]
name = "wandb" name = "wandb"
version = "0.21.4" version = "0.21.4"
@@ -2228,6 +2760,84 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" },
] ]
[[package]]
name = "websockets"
version = "15.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" },
{ url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" },
{ url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" },
{ url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" },
{ url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" },
{ url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" },
{ url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" },
{ url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" },
{ url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" },
{ url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" },
{ url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" },
{ url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" },
{ url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" },
{ url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" },
{ url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" },
{ url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" },
{ url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" },
{ url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" },
{ url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" },
{ url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" },
{ url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" },
{ url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" },
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" },
]
[[package]]
name = "xrobotoolkit-sdk"
version = "1.0.2"
source = { path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-linux_x86_64.whl" }
resolution-markers = [
"sys_platform == 'linux'",
"sys_platform != 'linux' and sys_platform != 'win32'",
]
dependencies = [
{ name = "packaging", marker = "sys_platform != 'win32'" },
{ name = "pybind11", marker = "sys_platform != 'win32'" },
{ name = "setuptools", marker = "sys_platform != 'win32'" },
]
wheels = [
{ filename = "xrobotoolkit_sdk-1.0.2-cp312-cp312-linux_x86_64.whl", hash = "sha256:f436bbc694b48a1bc65069aa6ffdc3d5c5e3d08f6be5e663a2a87a1f63ffd594" },
]
[package.metadata]
requires-dist = [
{ name = "packaging", specifier = ">=25.0" },
{ name = "pybind11", specifier = ">=3.0.1" },
{ name = "setuptools", specifier = ">=80.9.0" },
]
[[package]]
name = "xrobotoolkit-sdk"
version = "1.0.2"
source = { path = "whl/xrobotoolkit_sdk-1.0.2-cp312-cp312-win_amd64.whl" }
resolution-markers = [
"sys_platform == 'win32'",
]
dependencies = [
{ name = "packaging", marker = "sys_platform == 'win32'" },
{ name = "pybind11", marker = "sys_platform == 'win32'" },
{ name = "setuptools", marker = "sys_platform == 'win32'" },
]
wheels = [
{ filename = "xrobotoolkit_sdk-1.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:bca14a6ff9e0d059098547bef3228d686ecd64d11b0d897222e6c743f6191637" },
]
[package.metadata]
requires-dist = [
{ name = "packaging", specifier = ">=25.0" },
{ name = "pybind11", specifier = ">=3.0.1" },
{ name = "setuptools", specifier = ">=80.9.0" },
]
[[package]] [[package]]
name = "xxhash" name = "xxhash"
version = "3.6.0" version = "3.6.0"