├── models └── __init__.py ├── utils ├── __init__.py ├── image_processing.py ├── face_encoding.py ├── face_detection.py ├── face_storage.py └── face_quality.py ├── services ├── __init__.py ├── authentication.py ├── registration.py └── recognition.py ├── business └── xunfei │ ├── __init__.py │ ├── config.py │ ├── utils.py │ ├── face_feature_client.py │ ├── face_compare_client.py │ └── spark.py ├── .idea ├── vcs.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── modules.xml ├── poetry.xml ├── misc.xml ├── iflyface.iml └── workspace.xml ├── pyproject.toml ├── .gitignore ├── app.py └── poetry.lock /models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /business/xunfei/__init__.py: -------------------------------------------------------------------------------- 1 | from .face_compare_client import FaceCompareClient 2 | from .face_feature_client import FaceFeatureClient 3 | from .spark import SparkAPI 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/poetry.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /business/xunfei/config.py: -------------------------------------------------------------------------------- 1 | # 请填写控制台获取的APPID、APISecret、APIKey 2 | APP_ID = '142b649c' 3 | API_KEY_FACE_COMPARE = "3790438c24750aa9ed3b02ab6321c360" 4 | API_SECRET_FACE_COMPARE = 'ZGE2OWRlNjVkNzM0MzM5MzYwYWNkZTYy' 5 | SERVER_ID_FACE_COMPARE = 's67c9c78c' 6 | API_KEY_FACE_FEATURE = "002c130bd3c09614c4173a250b1ebd1b" 7 | API_KEY_SPARK = '3790438c24750aa9ed3b02ab6321c360' 8 | API_SECRET_SPARK = 'ZGE2OWRlNjVkNzM0MzM5MzYwYWNkZTYy' 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "iflyface" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["p0ise "] 6 | readme = "README.md" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.10" 10 | flask = "^3.0.2" 11 | requests = "^2.31.0" 12 | flask-cors = "^4.0.0" 13 | flask-socketio = "^5.3.6" 14 | opencv-python = "^4.9.0.80" 15 | facenet-pytorch = "^2.5.3" 16 | websocket-client = "^1.7.0" 17 | 18 | 19 | [build-system] 20 | requires = ["poetry-core"] 21 | build-backend = "poetry.core.masonry.api" 22 | -------------------------------------------------------------------------------- /utils/image_processing.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | import cv2 4 | import numpy as np 5 | from PIL import Image 6 | 7 | 8 | def cv2_to_pil(image): 9 | """Convert a CV2 image to PIL format.""" 10 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 11 | return Image.fromarray(image) 12 | 13 | 14 | def parse_frame_data(frame_data): 15 | """Parse frame data from base64 encoding.""" 16 | frame_data = base64.b64decode(frame_data.split(',')[1]) 17 | frame = np.frombuffer(frame_data, dtype=np.uint8) 18 | frame = cv2.imdecode(frame, flags=1) 19 | return cv2_to_pil(frame) 20 | -------------------------------------------------------------------------------- /.idea/iflyface.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /utils/face_encoding.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from facenet_pytorch import InceptionResnetV1 3 | from torchvision import transforms 4 | 5 | device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') 6 | resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device) 7 | 8 | 9 | def encode_face(face_image): 10 | """Encode a face image into a high-dimensional vector.""" 11 | preprocess = transforms.Compose([ 12 | transforms.Resize((160, 160)), 13 | transforms.ToTensor(), 14 | ]) 15 | face_tensor = preprocess(face_image).unsqueeze(0) 16 | with torch.no_grad(): 17 | face_encoding = resnet(face_tensor) 18 | return face_encoding.detach().cpu().numpy()[0] 19 | -------------------------------------------------------------------------------- /services/authentication.py: -------------------------------------------------------------------------------- 1 | from utils.face_detection import find_primary_face, align_face 2 | from utils.face_encoding import encode_face 3 | from utils.face_quality import evaluate_face_quality 4 | from utils.face_storage import FaceStorage 5 | 6 | face_storage = FaceStorage() 7 | 8 | 9 | def authenticate_face(image): 10 | """ 11 | 对给定的图像进行人脸认证。 12 | 13 | 参数: 14 | - image: 包含用户人脸的图像(PIL.Image格式)。 15 | 16 | 返回: 17 | - 认证成功与否的布尔值以及相应的消息。 18 | """ 19 | primary_face = find_primary_face(image) 20 | if primary_face: 21 | box, prob, landmark = primary_face 22 | if evaluate_face_quality(box, prob, image, landmark): 23 | aligned_face = align_face(image, box, landmark) 24 | face_encoding = encode_face(aligned_face) 25 | matched_face = face_storage.match_face(face_encoding) 26 | if matched_face: 27 | return True, matched_face['name'] 28 | else: 29 | return False, "认证失败,未知人脸,请先注册" 30 | else: 31 | return False, "人脸质量不符合要求" 32 | else: 33 | return False, "未检测到人脸" 34 | -------------------------------------------------------------------------------- /services/registration.py: -------------------------------------------------------------------------------- 1 | from utils.face_detection import find_primary_face, align_face 2 | from utils.face_encoding import encode_face 3 | from utils.face_quality import is_face_forward, evaluate_face_quality 4 | from utils.face_storage import FaceStorage 5 | 6 | face_storage = FaceStorage() 7 | 8 | 9 | def register_face(image, username): 10 | """ 11 | 注册新的用户人脸。 12 | 13 | 参数: 14 | - image: 包含用户人脸的图像(PIL.Image格式)。 15 | - username: 用户的名称。 16 | 17 | 返回: 18 | - 成功或失败的消息。 19 | """ 20 | primary_face = find_primary_face(image) 21 | if primary_face: 22 | box, prob, landmark = primary_face 23 | if is_face_forward(landmark) and evaluate_face_quality(box, prob, image, landmark): 24 | aligned_face = align_face(image, box, landmark) 25 | face_encoding = encode_face(aligned_face) 26 | matched_face = face_storage.match_face(face_encoding) 27 | if matched_face is None: 28 | face = face_storage.add_known_face(face_encoding, username) 29 | face_id = face['id'] 30 | return True, username 31 | else: 32 | return False, "人脸已注册" 33 | else: 34 | return False, "人脸质量不符合要求或非正脸" 35 | else: 36 | return False, "未检测到人脸" 37 | -------------------------------------------------------------------------------- /business/xunfei/utils.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hashlib 3 | import hmac 4 | import mimetypes 5 | 6 | 7 | class AssembleHeaderException(Exception): 8 | pass 9 | 10 | 11 | def parse_url(request_url): 12 | stidx = request_url.index("://") 13 | host = request_url[stidx + 3:] 14 | schema = request_url[:stidx + 3] 15 | edidx = host.index("/") 16 | if edidx <= 0: 17 | raise AssembleHeaderException("Invalid request URL: " + request_url) 18 | path = host[edidx:] 19 | host = host[:edidx] 20 | return schema, host, path 21 | 22 | 23 | def generate_signature(api_secret, host, date, method, path): 24 | signature_origin = f"host: {host}\ndate: {date}\n{method} {path} HTTP/1.1" 25 | signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'), 26 | digestmod=hashlib.sha256).digest() 27 | return base64.b64encode(signature_sha).decode('utf-8') 28 | 29 | 30 | def assemble_authorization_header(api_key, signature_sha): 31 | authorization_origin = (f'api_key="{api_key}", algorithm="hmac-sha256", ' 32 | f'headers="host date request-line", signature="{signature_sha}"') 33 | return base64.b64encode(authorization_origin.encode('utf-8')).decode('utf-8') 34 | 35 | 36 | def encode_image(image_path): 37 | """ 38 | 对图片文件进行Base64编码,并自动检测图片类型。 39 | 返回编码后的图片字符串和图片类型。 40 | """ 41 | # 检测文件类型 42 | mime_type, _ = mimetypes.guess_type(image_path) 43 | if mime_type is None: 44 | raise ValueError("Cannot determine the file type of the image.") 45 | # 获取文件的扩展名,例如 "image/jpeg" -> "jpeg" 46 | file_type = mime_type.split('/')[-1] 47 | 48 | with open(image_path, 'rb') as image_file: 49 | encoded_string = base64.b64encode(image_file.read()).decode('utf-8') 50 | return encoded_string, file_type 51 | -------------------------------------------------------------------------------- /utils/face_detection.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import torch 4 | from PIL import Image 5 | from facenet_pytorch import MTCNN 6 | 7 | device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') 8 | mtcnn = MTCNN(keep_all=True, device=device) 9 | 10 | 11 | def find_faces(image): 12 | # 使用MTCNN检测人脸,同时返回框、置信度和关键点 13 | boxes, probs, landmarks = mtcnn.detect(image, landmarks=True) 14 | if boxes is not None: 15 | return boxes, probs, landmarks 16 | else: 17 | return [], [], [] 18 | 19 | 20 | def find_primary_face(image): 21 | """ 22 | 查找图像中最显著的人脸。 23 | 24 | 参数: 25 | - image: PIL.Image对象,包含待检测的图像。 26 | 27 | 返回: 28 | - primary_face: 最显著的人脸信息,包括框、置信度和关键点。 29 | 如果没有检测到人脸,则返回None。 30 | """ 31 | boxes, probs, landmarks = mtcnn.detect(image, landmarks=True) 32 | if boxes is not None: 33 | return boxes[0], probs[0], landmarks[0] 34 | else: 35 | return None 36 | 37 | 38 | def align_face(image, box, landmark): 39 | # 计算两眼之间的角度 40 | eye_left = np.array(landmark[0]) 41 | eye_right = np.array(landmark[1]) 42 | d_y = eye_right[1] - eye_left[1] 43 | d_x = eye_right[0] - eye_left[0] 44 | angle = np.degrees(np.arctan2(d_y, d_x)) 45 | 46 | # 计算box中心作为旋转中心 47 | box_center = ((box[0] + box[2]) / 2, (box[1] + box[3]) / 2) 48 | 49 | # 将PIL.Image转换为numpy数组以便使用cv2函数处理 50 | image_np = np.array(image) 51 | 52 | # 应用仿射变换对齐整个画面 53 | scale = 1 54 | M = cv2.getRotationMatrix2D(box_center, angle, scale) 55 | rotated_image_np = cv2.warpAffine(image_np, M, (image_np.shape[1], image_np.shape[0])) 56 | 57 | # 将旋转后的numpy数组图像转换回PIL.Image 58 | rotated_image = Image.fromarray(rotated_image_np) 59 | 60 | # 从旋转后的图像中截取人脸区域 61 | face_image = rotated_image.crop(box) 62 | 63 | # 缩放图像到指定的尺寸 64 | aligned_face = face_image.resize((160, 160)) 65 | 66 | return aligned_face 67 | -------------------------------------------------------------------------------- /utils/face_storage.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | import numpy as np 4 | 5 | 6 | class SingletonMeta(type): 7 | _instances = {} 8 | 9 | def __call__(cls, *args, **kwargs): 10 | if cls not in cls._instances: 11 | instance = super().__call__(*args, **kwargs) 12 | cls._instances[cls] = instance 13 | return cls._instances[cls] 14 | 15 | 16 | class FaceStorage(metaclass=SingletonMeta): 17 | def __init__(self): 18 | self.known_faces = [] # 存储已知人脸的信息,每个条目是一个字典 19 | 20 | def add_known_face(self, face_encoding, name): 21 | """将新的人脸编码和名称添加到存储中""" 22 | face_id = str(uuid.uuid4()) # 生成唯一标识符 23 | face = { 24 | "id": face_id, 25 | "name": name, 26 | "encoding": face_encoding 27 | } 28 | self.known_faces.append(face) 29 | return face 30 | 31 | def match_face(self, face_encoding, tolerance=0.6): 32 | """在已知的人脸编码中寻找匹配项""" 33 | if not self.known_faces: 34 | return None 35 | distances = np.linalg.norm([face["encoding"] for face in self.known_faces] - face_encoding, axis=1) 36 | best_match_index = np.argmin(distances) 37 | if distances[best_match_index] < tolerance: 38 | return self.known_faces[best_match_index] 39 | return None 40 | 41 | def update_face_encoding(self, face_id, new_encoding): 42 | """根据人脸ID更新人脸编码""" 43 | for face in self.known_faces: 44 | if face["id"] == face_id: 45 | face["encoding"] = new_encoding 46 | return True 47 | return False 48 | 49 | def rename_face(self, face_id, new_name): 50 | """根据人脸ID更新人脸名称""" 51 | for face in self.known_faces: 52 | if face["id"] == face_id: 53 | face["name"] = new_name 54 | return True 55 | return False 56 | 57 | def get_face_info(self, face_id): 58 | """根据人脸ID获取人脸信息""" 59 | for face in self.known_faces: 60 | if face["id"] == face_id: 61 | return face 62 | return None 63 | -------------------------------------------------------------------------------- /business/xunfei/face_feature_client.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hashlib 3 | import os.path 4 | import time 5 | from urllib.parse import urljoin 6 | 7 | import requests 8 | 9 | from .config import APP_ID, API_KEY_FACE_FEATURE 10 | 11 | 12 | class FaceFeatureClient: 13 | def __init__(self): 14 | self.base_url = "http://tupapi.xfyun.cn/v1/" 15 | self.types = ['age', 'sex', 'expression', 'face_score'] 16 | 17 | def get_header(self, image_name): 18 | cur_time = str(int(time.time())) 19 | # param = {"image_name": image_name, "image_url": ''} 20 | param = "{\"image_name\":\"" + image_name + "\",\"image_url\":\"\"}" 21 | param_base64 = base64.b64encode(param.encode("utf-8")) 22 | 23 | m2 = hashlib.md5() 24 | m2.update((API_KEY_FACE_FEATURE + cur_time + str(param_base64, 'utf-8')).encode('utf-8')) 25 | check_sum = m2.hexdigest() 26 | 27 | header = { 28 | 'X-CurTime': cur_time, 29 | 'X-Param': param_base64, 30 | 'X-Appid': APP_ID, 31 | 'X-CheckSum': check_sum, 32 | } 33 | return header 34 | 35 | def analyze(self, type, image_path): 36 | url = urljoin(self.base_url, type) 37 | image_name = os.path.basename(image_path) 38 | headers = self.get_header(image_name) 39 | with open(image_path, 'rb') as f: 40 | data = f.read() 41 | response = requests.post(url, data, headers=headers) 42 | if response.status_code == 200: 43 | result = response.json() 44 | code = result['code'] 45 | if code == 0: 46 | value = result['data']['fileList'][0]['label'] 47 | else: 48 | value = result['desc'] 49 | else: 50 | code = -1 51 | value = '请求错误' 52 | 53 | return code, value 54 | 55 | def analyze_all(self, image_path): 56 | results = {} 57 | for type in self.types: 58 | code, value = self.analyze(type, image_path) 59 | if code == 0: 60 | results[type] = value 61 | return {"results": results} 62 | -------------------------------------------------------------------------------- /utils/face_quality.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def is_face_forward(landmarks): 5 | """ 6 | 判断人脸是否正对相机,并考虑人脸的俯仰角。 7 | 8 | 参数: 9 | - landmarks: 人脸的关键点坐标,假设是一个包含五个关键点(两只眼睛、鼻尖、两只嘴角)的列表。 10 | 11 | 返回: 12 | - is_forward: 布尔值,表示人脸是否正对相机,没有显著的俯仰、偏航或滚动角。 13 | """ 14 | # 提取两只眼睛和鼻尖的坐标 15 | eye_left = np.array(landmarks[0]) 16 | eye_right = np.array(landmarks[1]) 17 | nose = np.array(landmarks[2]) 18 | mouth_left = np.array(landmarks[3]) 19 | mouth_right = np.array(landmarks[4]) 20 | 21 | # 计算中点 22 | eye_center = (eye_left + eye_right) / 2 23 | 24 | # 计算方向向量 25 | direction_vector = eye_right - eye_left 26 | 27 | # 计算单位向量 28 | unit_vector = direction_vector / np.linalg.norm(direction_vector) 29 | 30 | # 计算鼻子到左右眼连线的向量 31 | nose_to_eye_line_vector = nose - eye_left 32 | 33 | # 计算投影长度 34 | projection_length = np.dot(nose_to_eye_line_vector, unit_vector) 35 | 36 | # 计算垂足坐标 37 | foot_of_perpendicular = eye_left + projection_length * unit_vector 38 | 39 | # 计算垂足到中点的距离 40 | foot_offset = np.linalg.norm(foot_of_perpendicular - eye_center) 41 | eye_dist = np.linalg.norm(eye_right - eye_left) 42 | 43 | # 设定偏移量阈值,判断是否为正面 44 | threshold = 0.1 * eye_dist 45 | if foot_offset < threshold: 46 | return True 47 | else: 48 | return False 49 | 50 | 51 | def evaluate_face_quality(box, prob, image, landmarks, quality_threshold=0.8): 52 | """ 53 | 根据人脸的大小、置信度和其他因素来评估人脸的质量。 54 | 返回是否通过质量检查。 55 | 56 | 参数: 57 | - box: 人脸框(x1, y1, x2, y2) 58 | - prob: 人脸检测的置信度 59 | - image: 包含人脸的图像(PIL.Image格式) 60 | - landmarks: 人脸的关键点坐标 61 | - quality_threshold: 质量评分的阈值,高于此阈值表示质量足够 62 | 63 | 返回: 64 | - boolean: 表示人脸是否通过质量检查 65 | """ 66 | # 基于人脸大小和置信度的简单评分:0-1 67 | face_area = (box[2] - box[0]) * (box[3] - box[1]) 68 | size_score = np.sqrt(face_area) / 160 if np.sqrt(face_area) / 160 <= 1 else 1 69 | 70 | # 置信度分数,prob在0到1之间 71 | confidence_score = prob 72 | 73 | # 综合评分 74 | quality_score = size_score * confidence_score 75 | 76 | if quality_score > quality_threshold: 77 | return True 78 | else: 79 | return False 80 | -------------------------------------------------------------------------------- /business/xunfei/face_compare_client.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import json 3 | from datetime import datetime 4 | from urllib.parse import urlencode 5 | 6 | import requests 7 | 8 | from .config import APP_ID, API_KEY_FACE_COMPARE, API_SECRET_FACE_COMPARE, SERVER_ID_FACE_COMPARE 9 | from .utils import parse_url, generate_signature, assemble_authorization_header, encode_image 10 | 11 | 12 | class FaceCompareClient: 13 | def __init__(self): 14 | self.base_url = f'http://api.xf-yun.com/v1/private/{SERVER_ID_FACE_COMPARE}' 15 | 16 | def generate_request_url(self): 17 | schema, host, path = parse_url(self.base_url) 18 | date = format(datetime.utcnow(), '%a, %d %b %Y %H:%M:%S GMT') 19 | signature_sha = generate_signature(API_SECRET_FACE_COMPARE, host, date, "POST", path) 20 | authorization = assemble_authorization_header(API_KEY_FACE_COMPARE, signature_sha) 21 | values = {"host": host, "date": date, "authorization": authorization} 22 | return f"{self.base_url}?{urlencode(values)}" 23 | 24 | def compare_faces(self, img1_path, img2_path): 25 | code = 0 26 | data = None 27 | 28 | request_url = self.generate_request_url() 29 | headers = {'content-type': "application/json", 'host': 'api.xf-yun.com', 'app_id': APP_ID} 30 | 31 | img1_encoded, img1_type = encode_image(img1_path) 32 | img2_encoded, img2_type = encode_image(img2_path) 33 | 34 | body = json.dumps({ 35 | "header": {"app_id": APP_ID, "status": 3}, 36 | "parameter": {SERVER_ID_FACE_COMPARE: {"service_kind": "face_compare", 37 | "face_compare_result": {"encoding": "utf8", "compress": "raw", 38 | "format": "json"}}}, 39 | "payload": { 40 | "input1": {"encoding": img1_type, "status": 3, "image": img1_encoded}, 41 | "input2": {"encoding": img2_type, "status": 3, "image": img2_encoded} 42 | } 43 | }) 44 | 45 | response = requests.post(request_url, data=body, headers=headers) 46 | if response.status_code == 200: 47 | result = json.loads(response.text) 48 | code = result['header']['code'] 49 | if code == 0: 50 | compare_result = json.loads(base64.b64decode(result['payload']['face_compare_result']['text'])) 51 | code = compare_result['ret'] 52 | if code == 0: 53 | data = compare_result['score'] 54 | else: 55 | data = '非人像图片' 56 | else: 57 | data = result['header']['message'] 58 | else: 59 | code = -1 60 | data = '请求错误' 61 | 62 | return code, data 63 | -------------------------------------------------------------------------------- /services/recognition.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from utils.face_detection import find_faces, align_face 4 | from utils.face_encoding import encode_face 5 | from utils.face_quality import is_face_forward, evaluate_face_quality 6 | from utils.face_storage import FaceStorage 7 | 8 | face_storage = FaceStorage() 9 | last_faces = [] 10 | last_face_boxes = [] 11 | 12 | 13 | def calculate_distance(box1, box2): 14 | center1 = ((box1[0] + box1[2]) / 2, (box1[1] + box1[3]) / 2) 15 | center2 = ((box2[0] + box2[2]) / 2, (box2[1] + box2[3]) / 2) 16 | distance = np.sqrt((center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2) 17 | return distance 18 | 19 | 20 | def has_new_face(face_boxes, threshold=50): 21 | global last_face_boxes, last_faces 22 | if len(face_boxes) == 0: 23 | return False 24 | # 如果当前帧和上一帧检测到的人脸数量不同,则认为有新的人脸出现 25 | if len(face_boxes) != len(last_face_boxes): 26 | return True 27 | else: 28 | # 计算当前帧与上一帧中人脸位置的最小距离 29 | for box in face_boxes: 30 | is_far = True 31 | for last_box in last_face_boxes: 32 | distance = calculate_distance(box, last_box) 33 | # 如果当前人脸与上一帧中所有人脸的最小距离超过阈值,则认为是新的人脸 34 | if distance <= threshold: 35 | is_far = False 36 | break 37 | if is_far: 38 | return True 39 | 40 | return False 41 | 42 | 43 | def recognize_faces(image): 44 | global last_face_boxes, last_faces 45 | boxes, probs, landmarks = find_faces(image) 46 | 47 | faces = [] 48 | if has_new_face(boxes) or any(face['name'] == "忽略" for face in last_faces): 49 | for box, prob, landmark in zip(boxes, probs, landmarks): 50 | is_forward = is_face_forward(landmark) 51 | face_quality_ok = evaluate_face_quality(box, prob, image, landmark) 52 | 53 | if is_forward and face_quality_ok: 54 | aligned_face = align_face(image, box, landmark) 55 | face_encoding = encode_face(aligned_face) 56 | face = face_storage.match_face(face_encoding) 57 | if face is None: 58 | face = face_storage.add_known_face(face_encoding, "未知") 59 | else: 60 | face = {'id': None, 'name': "忽略"} 61 | 62 | faces.append(face) 63 | else: 64 | faces = last_faces 65 | 66 | last_face_boxes = boxes 67 | last_faces = faces 68 | 69 | # 构建识别结果,包括未识别和被忽略的人脸 70 | recognized_faces = [] 71 | for face, (left, top, right, bottom), prob, landmark in zip(faces, boxes, probs, landmarks): 72 | face_id = face['id'] 73 | name = face['name'] 74 | location = (top, right, bottom, left) 75 | recognized_faces.append({ 76 | 'id': face_id, 77 | 'location': location, 78 | 'name': name, 79 | 'prob': prob, 80 | 'landmark': landmark.tolist() 81 | }) 82 | 83 | return recognized_faces 84 | 85 | 86 | def rename_face(face_id, name): 87 | face_storage.rename_face(face_id, name) 88 | -------------------------------------------------------------------------------- /business/xunfei/spark.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hashlib 3 | import hmac 4 | import json 5 | import ssl 6 | from datetime import datetime 7 | from time import mktime 8 | from urllib.parse import urlencode, urlparse 9 | from wsgiref.handlers import format_date_time 10 | 11 | import websocket 12 | 13 | from .config import APP_ID, API_KEY_SPARK, API_SECRET_SPARK 14 | 15 | 16 | class SparkAPI: 17 | def __init__(self, app_id: str = APP_ID, api_key: str = API_KEY_SPARK, api_secret: str = API_SECRET_SPARK, 18 | service_url: str = "wss://spark-api.xf-yun.com/v3.5/chat"): 19 | self.app_id = app_id 20 | self.api_key = api_key 21 | self.api_secret = api_secret 22 | self.host = urlparse(service_url).netloc 23 | self.path = urlparse(service_url).path 24 | self.service_url = service_url 25 | self.domain = self._get_model_domain(self.path) 26 | 27 | def _get_model_domain(self, path: str) -> str: 28 | domain_map = { 29 | "/v1.1/chat": "general", 30 | "/v2.1/chat": "generalv2", 31 | "/v3.1/chat": "generalv3", 32 | "/v3.5/chat": "generalv3.5", 33 | } 34 | return domain_map.get(path, "unknown") 35 | 36 | def generate_auth_url(self) -> str: 37 | timestamp = datetime.now() 38 | formatted_date = format_date_time(mktime(timestamp.timetuple())) 39 | signature = self._create_signature(formatted_date) 40 | authorization_origin = f'api_key="{self.api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature}"' 41 | authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode('utf-8') 42 | url_params = {"authorization": authorization, "date": formatted_date, "host": self.host} 43 | return f"{self.service_url}?{urlencode(url_params)}" 44 | 45 | def _create_signature(self, date: str) -> str: 46 | signature_origin = f"host: {self.host}\ndate: {date}\nGET {self.path} HTTP/1.1" 47 | signature_sha = hmac.new(self.api_secret.encode('utf-8'), signature_origin.encode('utf-8'), 48 | hashlib.sha256).digest() 49 | return base64.b64encode(signature_sha).decode('utf-8') 50 | 51 | def connect_and_query(self, on_message, messages: list): 52 | url = self.generate_auth_url() 53 | websocket.enableTrace(False) 54 | ws = websocket.WebSocketApp(url, 55 | on_message=lambda ws, msg: self.on_message(on_message, msg), 56 | on_error=self.on_error, 57 | on_close=self.on_close, 58 | on_open=lambda ws: self.on_open(ws, messages)) 59 | ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) 60 | 61 | def on_message(self, on_message, message: str): 62 | data = json.loads(message) 63 | on_message(data) 64 | 65 | def on_error(self, ws, error): 66 | print(f"WebSocket error: {error}") 67 | 68 | def on_close(self, ws, close_status_code, close_msg): 69 | print("WebSocket closed") 70 | 71 | def on_open(self, ws, messages): 72 | data = { 73 | "header": { 74 | "app_id": self.app_id, 75 | "uid": "1234" 76 | }, 77 | "parameter": { 78 | "chat": { 79 | "domain": self.domain, 80 | "temperature": 0.5, 81 | "max_tokens": 4096, 82 | "top_k": 5, 83 | "auditing": "default" 84 | } 85 | }, 86 | "payload": { 87 | "message": { 88 | "text": messages 89 | } 90 | } 91 | } 92 | ws.send(json.dumps(data)) 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # IPython Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # dotenv 81 | .env 82 | 83 | # virtualenv 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | ### VirtualEnv template 93 | # Virtualenv 94 | # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ 95 | [Bb]in 96 | [Ii]nclude 97 | [Ll]ib 98 | [Ll]ib64 99 | [Ll]ocal 100 | [Ss]cripts 101 | pyvenv.cfg 102 | .venv 103 | pip-selfcheck.json 104 | 105 | ### JetBrains template 106 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 107 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 108 | 109 | # User-specific stuff 110 | .idea/**/workspace.xml 111 | .idea/**/tasks.xml 112 | .idea/**/usage.statistics.xml 113 | .idea/**/dictionaries 114 | .idea/**/shelf 115 | 116 | # AWS User-specific 117 | .idea/**/aws.xml 118 | 119 | # Generated files 120 | .idea/**/contentModel.xml 121 | 122 | # Sensitive or high-churn files 123 | .idea/**/dataSources/ 124 | .idea/**/dataSources.ids 125 | .idea/**/dataSources.local.xml 126 | .idea/**/sqlDataSources.xml 127 | .idea/**/dynamic.xml 128 | .idea/**/uiDesigner.xml 129 | .idea/**/dbnavigator.xml 130 | 131 | # Gradle 132 | .idea/**/gradle.xml 133 | .idea/**/libraries 134 | 135 | # Gradle and Maven with auto-import 136 | # When using Gradle or Maven with auto-import, you should exclude module files, 137 | # since they will be recreated, and may cause churn. Uncomment if using 138 | # auto-import. 139 | # .idea/artifacts 140 | # .idea/compiler.xml 141 | # .idea/jarRepositories.xml 142 | # .idea/modules.xml 143 | # .idea/*.iml 144 | # .idea/modules 145 | # *.iml 146 | # *.ipr 147 | 148 | # CMake 149 | cmake-build-*/ 150 | 151 | # Mongo Explorer plugin 152 | .idea/**/mongoSettings.xml 153 | 154 | # File-based project format 155 | *.iws 156 | 157 | # IntelliJ 158 | out/ 159 | 160 | # mpeltonen/sbt-idea plugin 161 | .idea_modules/ 162 | 163 | # JIRA plugin 164 | atlassian-ide-plugin.xml 165 | 166 | # Cursive Clojure plugin 167 | .idea/replstate.xml 168 | 169 | # SonarLint plugin 170 | .idea/sonarlint/ 171 | 172 | # Crashlytics plugin (for Android Studio and IntelliJ) 173 | com_crashlytics_export_strings.xml 174 | crashlytics.properties 175 | crashlytics-build.properties 176 | fabric.properties 177 | 178 | # Editor-based Rest Client 179 | .idea/httpRequests 180 | 181 | # Android studio 3.1+ serialized cache file 182 | .idea/caches/build_file_checksums.ser 183 | 184 | # idea folder, uncomment if you don't need it 185 | # .idea -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tempfile 3 | import uuid 4 | 5 | from flask import Flask, request, session 6 | from flask import jsonify 7 | from flask_cors import CORS 8 | from flask_socketio import SocketIO, Namespace, emit, disconnect 9 | 10 | from business.xunfei import FaceCompareClient, FaceFeatureClient, SparkAPI 11 | from services.authentication import authenticate_face 12 | from services.recognition import recognize_faces, rename_face 13 | from services.registration import register_face 14 | from utils.face_detection import find_primary_face 15 | from utils.face_quality import is_face_forward 16 | from utils.image_processing import parse_frame_data 17 | 18 | # Set this variable to "threading", "eventlet" or "gevent" to test the 19 | # different async modes, or leave it set to None for the application to choose 20 | # the best option based on installed packages. 21 | async_mode = None 22 | 23 | app = Flask(__name__) 24 | CORS(app) 25 | socketio = SocketIO(app, cors_allowed_origins="*") 26 | 27 | # 配置上传文件夹和允许的扩展 28 | UPLOAD_FOLDER = 'static/uploads' 29 | ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'bmp'} 30 | app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER 31 | 32 | 33 | # Utility function to check allowed file 34 | def allowed_file(filename): 35 | return '.' in filename and \ 36 | filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS 37 | 38 | 39 | # Utility function to generate a secure filename 40 | def secure_filename(filename): 41 | # 使用UUID或其他方法生成唯一的文件名 42 | unique_filename = str(uuid.uuid4()) 43 | ext = filename.rsplit('.', 1)[1].lower() if '.' in filename else '' 44 | safe_filename = f"{unique_filename}.{ext}" if ext else unique_filename 45 | return safe_filename 46 | 47 | 48 | # 讯飞API - 人脸比对 49 | @app.route('/api/xunfei/face-compare', methods=['POST']) 50 | def face_compare(): 51 | # 检查是否上传了两个文件 52 | if 'image1' not in request.files or 'image2' not in request.files: 53 | return jsonify({'error': '缺少文件参数'}), 400 54 | file1 = request.files['image1'] 55 | file2 = request.files['image2'] 56 | if file1.filename == '' or file2.filename == '': 57 | return jsonify({'error': '未选择文件'}), 400 58 | elif not allowed_file(file1.filename) or not allowed_file(file2.filename): 59 | return jsonify({'error': '文件类型不正确'}), 400 60 | 61 | # 使用临时文件 62 | with tempfile.TemporaryDirectory() as tmpdirname: 63 | filepath1 = os.path.join(tmpdirname, secure_filename(file1.filename)) 64 | filepath2 = os.path.join(tmpdirname, secure_filename(file2.filename)) 65 | 66 | file1.save(filepath1) 67 | file2.save(filepath2) 68 | 69 | # 调用人脸比对服务 70 | client = FaceCompareClient() 71 | code, data = client.compare_faces(filepath1, filepath2) 72 | 73 | if code == 0: 74 | return jsonify({'message': '比对成功', 'data': data}), 200 75 | else: 76 | return jsonify({'error': data}), 400 77 | 78 | 79 | # 讯飞API - 人脸特征分析 80 | @app.route('/api/xunfei/face-features', methods=['POST']) 81 | def face_features(): 82 | if 'image' not in request.files: 83 | return jsonify({'error': '缺少文件参数'}), 400 84 | file = request.files['image'] 85 | if file.filename == '': 86 | return jsonify({'error': '未选择文件或文件类型不正确'}), 400 87 | elif not allowed_file(file.filename): 88 | return jsonify({'error': '文件类型不正确'}), 400 89 | 90 | # 使用临时文件 91 | with tempfile.NamedTemporaryFile(delete=False) as tmpfile: 92 | file.save(tmpfile.name) 93 | # 分析人脸特征 94 | client = FaceFeatureClient() 95 | result = client.analyze_all(tmpfile.name) 96 | 97 | # 清理临时文件 98 | os.remove(tmpfile.name) 99 | return jsonify(result) 100 | 101 | 102 | # 人脸认证的命名空间 103 | class FaceAuthNamespace(Namespace): 104 | def on_connect(self): 105 | print("Client connected to Face Auth") 106 | 107 | def on_disconnect(self): 108 | print("Client disconnected from Face Auth") 109 | 110 | def on_frame(self, data): 111 | image_data = data['image'] 112 | timestamp = data['timestamp'] 113 | if image_data.endswith('data:,'): 114 | print('empty frame data') 115 | return 116 | image = parse_frame_data(image_data) 117 | 118 | primary_face = find_primary_face(image) 119 | if primary_face: 120 | box, prob, landmark = primary_face 121 | 122 | if is_face_forward(landmark): 123 | left, top, right, bottom = box 124 | location = (top, right, bottom, left) 125 | result = {'success': True, 'face': {'location': location, 'landmark': landmark.tolist()}, 126 | 'timestamp': timestamp} 127 | else: 128 | result = {'success': False, 'message': "人脸质量不符合要求或非正脸", 'timestamp': timestamp} 129 | else: 130 | result = {'success': False, 'message': "未检测到人脸", 'timestamp': timestamp} 131 | 132 | emit('detection_result', result) 133 | 134 | def on_register(self, data): 135 | """ 136 | 处理用户注册事件。 137 | """ 138 | image_data = data['image'] 139 | username = data['username'] 140 | if image_data.endswith('data:,'): 141 | result = {'success': False, 'message': "帧数据为空"} 142 | else: 143 | image = parse_frame_data(image_data) 144 | success, message = register_face(image, username) 145 | result = {'success': success, 'message': message} 146 | 147 | emit('register_response', result) 148 | 149 | def on_login(self, data): 150 | """ 151 | 处理用户登录事件。 152 | """ 153 | image_data = data['image'] 154 | if image_data.endswith('data:,'): 155 | print('Empty frame data') 156 | result = {'success': False, 'message': "帧数据为空"} 157 | else: 158 | image = parse_frame_data(image_data) 159 | success, message = authenticate_face(image) 160 | result = {'success': success, 'message': message} 161 | 162 | emit('login_response', result) 163 | 164 | 165 | # 实时人脸识别的命名空间 166 | class FaceRecognitionNamespace(Namespace): 167 | 168 | def on_disconnect_request(self): 169 | emit('my_response', 170 | {'data': 'Disconnected!', 'count': session['receive_count']}) 171 | disconnect() 172 | 173 | # WebSocket事件处理,接收视频帧 174 | def on_frame(self, data): 175 | image_data = data['image'] 176 | timestamp = data['timestamp'] 177 | if image_data.endswith('data:,'): 178 | print('empty frame data') 179 | return 180 | image = parse_frame_data(image_data) 181 | 182 | # 在这里调用你的人脸检测逻辑 183 | faces = recognize_faces(image) 184 | emit('detection_results', {'faces': faces, 'timestamp': timestamp}) 185 | 186 | def on_rename_face(self, data): 187 | # TODO: 增加对重命名结果的处理 188 | face_id = data['id'] 189 | name = data['name'] 190 | rename_face(face_id, name) 191 | 192 | def on_connect(self): 193 | print("Client connected to Face Recognition") 194 | 195 | def on_disconnect(self): 196 | print('Client disconnected from Face Recognition', request.sid) 197 | 198 | 199 | class ChatNamespace(Namespace): 200 | 201 | def on_connect(self): 202 | print("Client connected to Chat") 203 | 204 | def on_disconnect(self): 205 | print('Client disconnected from Chat', request.sid) 206 | 207 | def on_send_message(self, data): 208 | messages = data['messages'] 209 | spark_api = SparkAPI() 210 | spark_api.connect_and_query(self.on_response, messages) 211 | return jsonify({"status": "connecting"}) 212 | 213 | def on_response(self, data): 214 | if data['header']['code'] != 0: 215 | print(data['header']['code']) 216 | emit('error', {'error': f"Error from API: {data['header']['code']}"}) 217 | else: 218 | choices = data["payload"]['choices'] 219 | status = choices['status'] 220 | seq = choices['seq'] 221 | text = choices['text'][0] 222 | emit('message_response', { 223 | 'status': status, 224 | 'seq': seq, 225 | 'text': { 226 | 'role': text['role'], 227 | 'content': text['content'] 228 | } 229 | }) 230 | 231 | 232 | # 注册命名空间 233 | socketio.on_namespace(FaceAuthNamespace('/api/face-auth')) 234 | socketio.on_namespace(FaceRecognitionNamespace('/api/face-recognition')) 235 | 236 | socketio.on_namespace(ChatNamespace('/api/chat')) 237 | 238 | if __name__ == '__main__': 239 | socketio.run(app, debug=True, allow_unsafe_werkzeug=True) 240 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 39 | { 40 | "lastFilter": { 41 | "state": "OPEN", 42 | "assignee": "p0ise" 43 | } 44 | } 45 | { 46 | "selectedUrlAndAccountId": { 47 | "url": "https://github.com/p0ise/iflyface-backend.git", 48 | "accountId": "1410cdc2-b2ba-469b-ae38-28d431d2598e" 49 | } 50 | } 51 | { 52 | "associatedIndex": 7 53 | } 54 | 55 | 56 | 57 | 58 | 59 | 62 | { 63 | "keyToString": { 64 | "DefaultHtmlFileTemplate": "HTML File", 65 | "Flask 服务器.Flask (hello.py).executor": "Run", 66 | "Flask 服务器.iflyface.executor": "Run", 67 | "Python.app.executor": "Run", 68 | "Python.face_recognition.executor": "Run", 69 | "Python.spark.executor": "Run", 70 | "Python.sparkdemo.executor": "Run", 71 | "RunOnceActivity.OpenProjectViewOnStart": "true", 72 | "RunOnceActivity.ShowReadmeOnStart": "true", 73 | "SHARE_PROJECT_CONFIGURATION_FILES": "true", 74 | "git-widget-placeholder": "master", 75 | "ignore.virus.scanning.warn.message": "true", 76 | "last_opened_file_path": "C:/Users/ADMIN/PycharmProjects/iflyface-backend", 77 | "node.js.detected.package.eslint": "true", 78 | "node.js.detected.package.tslint": "true", 79 | "node.js.selected.package.eslint": "(autodetect)", 80 | "node.js.selected.package.tslint": "(autodetect)", 81 | "nodejs_package_manager_path": "npm", 82 | "settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable", 83 | "vue.rearranger.settings.migration": "true" 84 | } 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 120 | 121 | 122 | 143 | 144 | 145 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 1711421904128 179 | 198 | 199 | 206 | 207 | 214 | 215 | 222 | 223 | 230 | 231 | 238 | 239 | 246 | 247 | 254 | 255 | 262 | 263 | 270 | 271 | 278 | 279 | 286 | 287 | 294 | 295 | 302 | 303 | 310 | 311 | 318 | 319 | 326 | 327 | 334 | 335 | 342 | 343 | 350 | 351 | 358 | 359 | 366 | 367 | 374 | 375 | 382 | 383 | 390 | 391 | 398 | 399 | 406 | 407 | 414 | 415 | 422 | 425 | 426 | 428 | 429 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "bidict" 3 | version = "0.23.1" 4 | description = "The bidirectional mapping library for Python." 5 | category = "main" 6 | optional = false 7 | python-versions = ">=3.8" 8 | 9 | [[package]] 10 | name = "blinker" 11 | version = "1.7.0" 12 | description = "Fast, simple object-to-object and broadcast signaling" 13 | category = "main" 14 | optional = false 15 | python-versions = ">=3.8" 16 | 17 | [[package]] 18 | name = "certifi" 19 | version = "2024.2.2" 20 | description = "Python package for providing Mozilla's CA Bundle." 21 | category = "main" 22 | optional = false 23 | python-versions = ">=3.6" 24 | 25 | [[package]] 26 | name = "charset-normalizer" 27 | version = "3.3.2" 28 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 29 | category = "main" 30 | optional = false 31 | python-versions = ">=3.7.0" 32 | 33 | [[package]] 34 | name = "click" 35 | version = "8.1.7" 36 | description = "Composable command line interface toolkit" 37 | category = "main" 38 | optional = false 39 | python-versions = ">=3.7" 40 | 41 | [package.dependencies] 42 | colorama = { version = "*", markers = "platform_system == \"Windows\"" } 43 | 44 | [[package]] 45 | name = "colorama" 46 | version = "0.4.6" 47 | description = "Cross-platform colored terminal text." 48 | category = "main" 49 | optional = false 50 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 51 | 52 | [[package]] 53 | name = "facenet-pytorch" 54 | version = "2.5.3" 55 | description = "Pretrained Pytorch face detection and recognition models" 56 | category = "main" 57 | optional = false 58 | python-versions = "*" 59 | 60 | [package.dependencies] 61 | numpy = "*" 62 | pillow = "*" 63 | requests = "*" 64 | torchvision = "*" 65 | 66 | [[package]] 67 | name = "filelock" 68 | version = "3.13.3" 69 | description = "A platform independent file lock." 70 | category = "main" 71 | optional = false 72 | python-versions = ">=3.8" 73 | 74 | [package.extras] 75 | docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] 76 | testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] 77 | typing = ["typing-extensions (>=4.8)"] 78 | 79 | [[package]] 80 | name = "flask" 81 | version = "3.0.3" 82 | description = "A simple framework for building complex web applications." 83 | category = "main" 84 | optional = false 85 | python-versions = ">=3.8" 86 | 87 | [package.dependencies] 88 | blinker = ">=1.6.2" 89 | click = ">=8.1.3" 90 | itsdangerous = ">=2.1.2" 91 | Jinja2 = ">=3.1.2" 92 | Werkzeug = ">=3.0.0" 93 | 94 | [package.extras] 95 | async = ["asgiref (>=3.2)"] 96 | dotenv = ["python-dotenv"] 97 | 98 | [[package]] 99 | name = "flask-cors" 100 | version = "4.0.0" 101 | description = "A Flask extension adding a decorator for CORS support" 102 | category = "main" 103 | optional = false 104 | python-versions = "*" 105 | 106 | [package.dependencies] 107 | Flask = ">=0.9" 108 | 109 | [[package]] 110 | name = "flask-socketio" 111 | version = "5.3.6" 112 | description = "Socket.IO integration for Flask applications" 113 | category = "main" 114 | optional = false 115 | python-versions = ">=3.6" 116 | 117 | [package.dependencies] 118 | Flask = ">=0.9" 119 | python-socketio = ">=5.0.2" 120 | 121 | [package.extras] 122 | docs = ["sphinx"] 123 | 124 | [[package]] 125 | name = "fsspec" 126 | version = "2024.3.1" 127 | description = "File-system specification" 128 | category = "main" 129 | optional = false 130 | python-versions = ">=3.8" 131 | 132 | [package.extras] 133 | abfs = ["adlfs"] 134 | adl = ["adlfs"] 135 | arrow = ["pyarrow (>=1)"] 136 | dask = ["dask", "distributed"] 137 | devel = ["pytest", "pytest-cov"] 138 | dropbox = ["dropbox", "dropboxdrivefs", "requests"] 139 | full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] 140 | fuse = ["fusepy"] 141 | gcs = ["gcsfs"] 142 | git = ["pygit2"] 143 | github = ["requests"] 144 | gs = ["gcsfs"] 145 | gui = ["panel"] 146 | hdfs = ["pyarrow (>=1)"] 147 | http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] 148 | libarchive = ["libarchive-c"] 149 | oci = ["ocifs"] 150 | s3 = ["s3fs"] 151 | sftp = ["paramiko"] 152 | smb = ["smbprotocol"] 153 | ssh = ["paramiko"] 154 | tqdm = ["tqdm"] 155 | 156 | [[package]] 157 | name = "h11" 158 | version = "0.14.0" 159 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" 160 | category = "main" 161 | optional = false 162 | python-versions = ">=3.7" 163 | 164 | [[package]] 165 | name = "idna" 166 | version = "3.6" 167 | description = "Internationalized Domain Names in Applications (IDNA)" 168 | category = "main" 169 | optional = false 170 | python-versions = ">=3.5" 171 | 172 | [[package]] 173 | name = "itsdangerous" 174 | version = "2.1.2" 175 | description = "Safely pass data to untrusted environments and back." 176 | category = "main" 177 | optional = false 178 | python-versions = ">=3.7" 179 | 180 | [[package]] 181 | name = "jinja2" 182 | version = "3.1.3" 183 | description = "A very fast and expressive template engine." 184 | category = "main" 185 | optional = false 186 | python-versions = ">=3.7" 187 | 188 | [package.dependencies] 189 | MarkupSafe = ">=2.0" 190 | 191 | [package.extras] 192 | i18n = ["Babel (>=2.7)"] 193 | 194 | [[package]] 195 | name = "markupsafe" 196 | version = "2.1.5" 197 | description = "Safely add untrusted strings to HTML/XML markup." 198 | category = "main" 199 | optional = false 200 | python-versions = ">=3.7" 201 | 202 | [[package]] 203 | name = "mpmath" 204 | version = "1.3.0" 205 | description = "Python library for arbitrary-precision floating-point arithmetic" 206 | category = "main" 207 | optional = false 208 | python-versions = "*" 209 | 210 | [package.extras] 211 | develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] 212 | docs = ["sphinx"] 213 | gmpy = ["gmpy2 (>=2.1.0a4)"] 214 | tests = ["pytest (>=4.6)"] 215 | 216 | [[package]] 217 | name = "networkx" 218 | version = "3.3" 219 | description = "Python package for creating and manipulating graphs and networks" 220 | category = "main" 221 | optional = false 222 | python-versions = ">=3.10" 223 | 224 | [package.extras] 225 | default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] 226 | developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] 227 | doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] 228 | extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] 229 | test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] 230 | 231 | [[package]] 232 | name = "numpy" 233 | version = "1.26.4" 234 | description = "Fundamental package for array computing in Python" 235 | category = "main" 236 | optional = false 237 | python-versions = ">=3.9" 238 | 239 | [[package]] 240 | name = "nvidia-cublas-cu12" 241 | version = "12.1.3.1" 242 | description = "CUBLAS native runtime libraries" 243 | category = "main" 244 | optional = false 245 | python-versions = ">=3" 246 | 247 | [[package]] 248 | name = "nvidia-cuda-cupti-cu12" 249 | version = "12.1.105" 250 | description = "CUDA profiling tools runtime libs." 251 | category = "main" 252 | optional = false 253 | python-versions = ">=3" 254 | 255 | [[package]] 256 | name = "nvidia-cuda-nvrtc-cu12" 257 | version = "12.1.105" 258 | description = "NVRTC native runtime libraries" 259 | category = "main" 260 | optional = false 261 | python-versions = ">=3" 262 | 263 | [[package]] 264 | name = "nvidia-cuda-runtime-cu12" 265 | version = "12.1.105" 266 | description = "CUDA Runtime native Libraries" 267 | category = "main" 268 | optional = false 269 | python-versions = ">=3" 270 | 271 | [[package]] 272 | name = "nvidia-cudnn-cu12" 273 | version = "8.9.2.26" 274 | description = "cuDNN runtime libraries" 275 | category = "main" 276 | optional = false 277 | python-versions = ">=3" 278 | 279 | [package.dependencies] 280 | nvidia-cublas-cu12 = "*" 281 | 282 | [[package]] 283 | name = "nvidia-cufft-cu12" 284 | version = "11.0.2.54" 285 | description = "CUFFT native runtime libraries" 286 | category = "main" 287 | optional = false 288 | python-versions = ">=3" 289 | 290 | [[package]] 291 | name = "nvidia-curand-cu12" 292 | version = "10.3.2.106" 293 | description = "CURAND native runtime libraries" 294 | category = "main" 295 | optional = false 296 | python-versions = ">=3" 297 | 298 | [[package]] 299 | name = "nvidia-cusolver-cu12" 300 | version = "11.4.5.107" 301 | description = "CUDA solver native runtime libraries" 302 | category = "main" 303 | optional = false 304 | python-versions = ">=3" 305 | 306 | [package.dependencies] 307 | nvidia-cublas-cu12 = "*" 308 | nvidia-cusparse-cu12 = "*" 309 | nvidia-nvjitlink-cu12 = "*" 310 | 311 | [[package]] 312 | name = "nvidia-cusparse-cu12" 313 | version = "12.1.0.106" 314 | description = "CUSPARSE native runtime libraries" 315 | category = "main" 316 | optional = false 317 | python-versions = ">=3" 318 | 319 | [package.dependencies] 320 | nvidia-nvjitlink-cu12 = "*" 321 | 322 | [[package]] 323 | name = "nvidia-nccl-cu12" 324 | version = "2.19.3" 325 | description = "NVIDIA Collective Communication Library (NCCL) Runtime" 326 | category = "main" 327 | optional = false 328 | python-versions = ">=3" 329 | 330 | [[package]] 331 | name = "nvidia-nvjitlink-cu12" 332 | version = "12.4.127" 333 | description = "Nvidia JIT LTO Library" 334 | category = "main" 335 | optional = false 336 | python-versions = ">=3" 337 | 338 | [[package]] 339 | name = "nvidia-nvtx-cu12" 340 | version = "12.1.105" 341 | description = "NVIDIA Tools Extension" 342 | category = "main" 343 | optional = false 344 | python-versions = ">=3" 345 | 346 | [[package]] 347 | name = "opencv-python" 348 | version = "4.9.0.80" 349 | description = "Wrapper package for OpenCV python bindings." 350 | category = "main" 351 | optional = false 352 | python-versions = ">=3.6" 353 | 354 | [package.dependencies] 355 | numpy = [ 356 | { version = ">=1.21.2", markers = "python_version >= \"3.10\"" }, 357 | { version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\"" }, 358 | { version = ">=1.23.5", markers = "python_version >= \"3.11\"" }, 359 | { version = ">=1.26.0", markers = "python_version >= \"3.12\"" }, 360 | { version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\"" }, 361 | { version = ">=1.17.0", markers = "python_version >= \"3.7\"" }, 362 | { version = ">=1.17.3", markers = "python_version >= \"3.8\"" }, 363 | ] 364 | 365 | [[package]] 366 | name = "pillow" 367 | version = "10.3.0" 368 | description = "Python Imaging Library (Fork)" 369 | category = "main" 370 | optional = false 371 | python-versions = ">=3.8" 372 | 373 | [package.extras] 374 | docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] 375 | fpx = ["olefile"] 376 | mic = ["olefile"] 377 | tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] 378 | typing = ["typing-extensions"] 379 | xmp = ["defusedxml"] 380 | 381 | [[package]] 382 | name = "python-engineio" 383 | version = "4.9.0" 384 | description = "Engine.IO server and client for Python" 385 | category = "main" 386 | optional = false 387 | python-versions = ">=3.6" 388 | 389 | [package.dependencies] 390 | simple-websocket = ">=0.10.0" 391 | 392 | [package.extras] 393 | asyncio-client = ["aiohttp (>=3.4)"] 394 | client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] 395 | docs = ["sphinx"] 396 | 397 | [[package]] 398 | name = "python-socketio" 399 | version = "5.11.2" 400 | description = "Socket.IO server and client for Python" 401 | category = "main" 402 | optional = false 403 | python-versions = ">=3.8" 404 | 405 | [package.dependencies] 406 | bidict = ">=0.21.0" 407 | python-engineio = ">=4.8.0" 408 | 409 | [package.extras] 410 | asyncio-client = ["aiohttp (>=3.4)"] 411 | client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] 412 | docs = ["sphinx"] 413 | 414 | [[package]] 415 | name = "requests" 416 | version = "2.31.0" 417 | description = "Python HTTP for Humans." 418 | category = "main" 419 | optional = false 420 | python-versions = ">=3.7" 421 | 422 | [package.dependencies] 423 | certifi = ">=2017.4.17" 424 | charset-normalizer = ">=2,<4" 425 | idna = ">=2.5,<4" 426 | urllib3 = ">=1.21.1,<3" 427 | 428 | [package.extras] 429 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 430 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 431 | 432 | [[package]] 433 | name = "simple-websocket" 434 | version = "1.0.0" 435 | description = "Simple WebSocket server and client for Python" 436 | category = "main" 437 | optional = false 438 | python-versions = ">=3.6" 439 | 440 | [package.dependencies] 441 | wsproto = "*" 442 | 443 | [package.extras] 444 | docs = ["sphinx"] 445 | 446 | [[package]] 447 | name = "sympy" 448 | version = "1.12" 449 | description = "Computer algebra system (CAS) in Python" 450 | category = "main" 451 | optional = false 452 | python-versions = ">=3.8" 453 | 454 | [package.dependencies] 455 | mpmath = ">=0.19" 456 | 457 | [[package]] 458 | name = "torch" 459 | version = "2.2.2" 460 | description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" 461 | category = "main" 462 | optional = false 463 | python-versions = ">=3.8.0" 464 | 465 | [package.dependencies] 466 | filelock = "*" 467 | fsspec = "*" 468 | jinja2 = "*" 469 | networkx = "*" 470 | nvidia-cublas-cu12 = { version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 471 | nvidia-cuda-cupti-cu12 = { version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 472 | nvidia-cuda-nvrtc-cu12 = { version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 473 | nvidia-cuda-runtime-cu12 = { version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 474 | nvidia-cudnn-cu12 = { version = "8.9.2.26", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 475 | nvidia-cufft-cu12 = { version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 476 | nvidia-curand-cu12 = { version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 477 | nvidia-cusolver-cu12 = { version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 478 | nvidia-cusparse-cu12 = { version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 479 | nvidia-nccl-cu12 = { version = "2.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 480 | nvidia-nvtx-cu12 = { version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" } 481 | sympy = "*" 482 | triton = { version = "2.2.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\" and python_version < \"3.12\"" } 483 | typing-extensions = ">=4.8.0" 484 | 485 | [package.extras] 486 | opt-einsum = ["opt-einsum (>=3.3)"] 487 | optree = ["optree (>=0.9.1)"] 488 | 489 | [[package]] 490 | name = "torchvision" 491 | version = "0.17.2" 492 | description = "image and video datasets and models for torch deep learning" 493 | category = "main" 494 | optional = false 495 | python-versions = ">=3.8" 496 | 497 | [package.dependencies] 498 | numpy = "*" 499 | pillow = ">=5.3.0,<8.3.0 || >=8.4.0" 500 | torch = "2.2.2" 501 | 502 | [package.extras] 503 | scipy = ["scipy"] 504 | 505 | [[package]] 506 | name = "triton" 507 | version = "2.2.0" 508 | description = "A language and compiler for custom Deep Learning operations" 509 | category = "main" 510 | optional = false 511 | python-versions = "*" 512 | 513 | [package.dependencies] 514 | filelock = "*" 515 | 516 | [package.extras] 517 | build = ["cmake (>=3.20)", "lit"] 518 | tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)", "torch"] 519 | tutorials = ["matplotlib", "pandas", "tabulate", "torch"] 520 | 521 | [[package]] 522 | name = "typing-extensions" 523 | version = "4.11.0" 524 | description = "Backported and Experimental Type Hints for Python 3.8+" 525 | category = "main" 526 | optional = false 527 | python-versions = ">=3.8" 528 | 529 | [[package]] 530 | name = "urllib3" 531 | version = "2.2.1" 532 | description = "HTTP library with thread-safe connection pooling, file post, and more." 533 | category = "main" 534 | optional = false 535 | python-versions = ">=3.8" 536 | 537 | [package.extras] 538 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] 539 | h2 = ["h2 (>=4,<5)"] 540 | socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] 541 | zstd = ["zstandard (>=0.18.0)"] 542 | 543 | [[package]] 544 | name = "websocket-client" 545 | version = "1.7.0" 546 | description = "WebSocket client for Python with low level API options" 547 | category = "main" 548 | optional = false 549 | python-versions = ">=3.8" 550 | 551 | [package.extras] 552 | docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] 553 | optional = ["python-socks", "wsaccel"] 554 | test = ["websockets"] 555 | 556 | [[package]] 557 | name = "werkzeug" 558 | version = "3.0.2" 559 | description = "The comprehensive WSGI web application library." 560 | category = "main" 561 | optional = false 562 | python-versions = ">=3.8" 563 | 564 | [package.dependencies] 565 | MarkupSafe = ">=2.1.1" 566 | 567 | [package.extras] 568 | watchdog = ["watchdog (>=2.3)"] 569 | 570 | [[package]] 571 | name = "wsproto" 572 | version = "1.2.0" 573 | description = "WebSockets state-machine based protocol implementation" 574 | category = "main" 575 | optional = false 576 | python-versions = ">=3.7.0" 577 | 578 | [package.dependencies] 579 | h11 = ">=0.9.0,<1" 580 | 581 | [metadata] 582 | lock-version = "1.1" 583 | python-versions = "^3.10" 584 | content-hash = "957ce99cae5fd8d4a7b4b242751e99d3e83dc03e98d45f38868ef3b018a38c70" 585 | 586 | [metadata.files] 587 | bidict = [ 588 | { file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5" }, 589 | { file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71" }, 590 | ] 591 | blinker = [ 592 | { file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9" }, 593 | { file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" }, 594 | ] 595 | certifi = [ 596 | { file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" }, 597 | { file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f" }, 598 | ] 599 | charset-normalizer = [ 600 | { file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5" }, 601 | { file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3" }, 602 | { file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027" }, 603 | { file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03" }, 604 | { file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d" }, 605 | { file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e" }, 606 | { file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6" }, 607 | { file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5" }, 608 | { file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537" }, 609 | { file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c" }, 610 | { file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12" }, 611 | { file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f" }, 612 | { file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269" }, 613 | { file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519" }, 614 | { file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73" }, 615 | { file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09" }, 616 | { file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db" }, 617 | { file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96" }, 618 | { file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e" }, 619 | { file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f" }, 620 | { file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574" }, 621 | { file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4" }, 622 | { file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8" }, 623 | { file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc" }, 624 | { file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae" }, 625 | { file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887" }, 626 | { file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae" }, 627 | { file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce" }, 628 | { file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f" }, 629 | { file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab" }, 630 | { file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77" }, 631 | { file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8" }, 632 | { file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b" }, 633 | { file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6" }, 634 | { file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a" }, 635 | { file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389" }, 636 | { file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa" }, 637 | { file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b" }, 638 | { file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed" }, 639 | { file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26" }, 640 | { file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d" }, 641 | { file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068" }, 642 | { file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143" }, 643 | { file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4" }, 644 | { file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7" }, 645 | { file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001" }, 646 | { file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c" }, 647 | { file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5" }, 648 | { file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985" }, 649 | { file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6" }, 650 | { file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714" }, 651 | { file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786" }, 652 | { file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5" }, 653 | { file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c" }, 654 | { file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8" }, 655 | { file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711" }, 656 | { file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811" }, 657 | { file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4" }, 658 | { file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99" }, 659 | { file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a" }, 660 | { file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac" }, 661 | { file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a" }, 662 | { file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33" }, 663 | { file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238" }, 664 | { file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a" }, 665 | { file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2" }, 666 | { file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8" }, 667 | { file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898" }, 668 | { file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99" }, 669 | { file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d" }, 670 | { file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04" }, 671 | { file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087" }, 672 | { file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25" }, 673 | { file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b" }, 674 | { file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4" }, 675 | { file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d" }, 676 | { file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0" }, 677 | { file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269" }, 678 | { file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c" }, 679 | { file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519" }, 680 | { file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796" }, 681 | { file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185" }, 682 | { file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c" }, 683 | { file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458" }, 684 | { file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2" }, 685 | { file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8" }, 686 | { file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" }, 687 | { file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f" }, 688 | { file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d" }, 689 | { file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc" }, 690 | ] 691 | click = [ 692 | { file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28" }, 693 | { file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" }, 694 | ] 695 | colorama = [ 696 | { file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, 697 | { file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" }, 698 | ] 699 | facenet-pytorch = [ 700 | { file = "facenet-pytorch-2.5.3.tar.gz", hash = "sha256:98cc5b42a48f837c023eb92f2a571cd4ac6a46687c5e71b9e99b491087273e2b" }, 701 | { file = "facenet_pytorch-2.5.3-py3-none-any.whl", hash = "sha256:b8002c3ee7a3af471c433cbda1fdcab9ae2d46a4aac43435ba08259c45ffc884" }, 702 | ] 703 | filelock = [ 704 | { file = "filelock-3.13.3-py3-none-any.whl", hash = "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb" }, 705 | { file = "filelock-3.13.3.tar.gz", hash = "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546" }, 706 | ] 707 | flask = [ 708 | { file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3" }, 709 | { file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842" }, 710 | ] 711 | flask-cors = [ 712 | { file = "Flask-Cors-4.0.0.tar.gz", hash = "sha256:f268522fcb2f73e2ecdde1ef45e2fd5c71cc48fe03cffb4b441c6d1b40684eb0" }, 713 | { file = "Flask_Cors-4.0.0-py2.py3-none-any.whl", hash = "sha256:bc3492bfd6368d27cfe79c7821df5a8a319e1a6d5eab277a3794be19bdc51783" }, 714 | ] 715 | flask-socketio = [ 716 | { file = "Flask-SocketIO-5.3.6.tar.gz", hash = "sha256:bb8f9f9123ef47632f5ce57a33514b0c0023ec3696b2384457f0fcaa5b70501c" }, 717 | { file = "Flask_SocketIO-5.3.6-py3-none-any.whl", hash = "sha256:9e62d2131842878ae6bfdd7067dfc3be397c1f2b117ab1dc74e6fe74aad7a579" }, 718 | ] 719 | fsspec = [ 720 | { file = "fsspec-2024.3.1-py3-none-any.whl", hash = "sha256:918d18d41bf73f0e2b261824baeb1b124bcf771767e3a26425cd7dec3332f512" }, 721 | { file = "fsspec-2024.3.1.tar.gz", hash = "sha256:f39780e282d7d117ffb42bb96992f8a90795e4d0fb0f661a70ca39fe9c43ded9" }, 722 | ] 723 | h11 = [ 724 | { file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" }, 725 | { file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d" }, 726 | ] 727 | idna = [ 728 | { file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" }, 729 | { file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" }, 730 | ] 731 | itsdangerous = [ 732 | { file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44" }, 733 | { file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" }, 734 | ] 735 | jinja2 = [ 736 | { file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa" }, 737 | { file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90" }, 738 | ] 739 | markupsafe = [ 740 | { file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc" }, 741 | { file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5" }, 742 | { file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46" }, 743 | { file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f" }, 744 | { file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900" }, 745 | { file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff" }, 746 | { file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad" }, 747 | { file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd" }, 748 | { file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4" }, 749 | { file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5" }, 750 | { file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f" }, 751 | { file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2" }, 752 | { file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced" }, 753 | { file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5" }, 754 | { file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c" }, 755 | { file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f" }, 756 | { file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a" }, 757 | { file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f" }, 758 | { file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906" }, 759 | { file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617" }, 760 | { file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1" }, 761 | { file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4" }, 762 | { file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee" }, 763 | { file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5" }, 764 | { file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b" }, 765 | { file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a" }, 766 | { file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f" }, 767 | { file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169" }, 768 | { file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad" }, 769 | { file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb" }, 770 | { file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f" }, 771 | { file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf" }, 772 | { file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a" }, 773 | { file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52" }, 774 | { file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9" }, 775 | { file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df" }, 776 | { file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50" }, 777 | { file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371" }, 778 | { file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2" }, 779 | { file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a" }, 780 | { file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46" }, 781 | { file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532" }, 782 | { file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab" }, 783 | { file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" }, 784 | { file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0" }, 785 | { file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4" }, 786 | { file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3" }, 787 | { file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff" }, 788 | { file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029" }, 789 | { file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf" }, 790 | { file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2" }, 791 | { file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8" }, 792 | { file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3" }, 793 | { file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465" }, 794 | { file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e" }, 795 | { file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea" }, 796 | { file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6" }, 797 | { file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf" }, 798 | { file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5" }, 799 | { file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b" }, 800 | ] 801 | mpmath = [ 802 | { file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c" }, 803 | { file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f" }, 804 | ] 805 | networkx = [ 806 | { file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2" }, 807 | { file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9" }, 808 | ] 809 | numpy = [ 810 | { file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0" }, 811 | { file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a" }, 812 | { file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4" }, 813 | { file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" }, 814 | { file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a" }, 815 | { file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2" }, 816 | { file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07" }, 817 | { file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5" }, 818 | { file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71" }, 819 | { file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef" }, 820 | { file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e" }, 821 | { file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5" }, 822 | { file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a" }, 823 | { file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a" }, 824 | { file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20" }, 825 | { file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2" }, 826 | { file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218" }, 827 | { file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b" }, 828 | { file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b" }, 829 | { file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed" }, 830 | { file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a" }, 831 | { file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0" }, 832 | { file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110" }, 833 | { file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818" }, 834 | { file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c" }, 835 | { file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be" }, 836 | { file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764" }, 837 | { file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3" }, 838 | { file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd" }, 839 | { file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c" }, 840 | { file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6" }, 841 | { file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea" }, 842 | { file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30" }, 843 | { file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c" }, 844 | { file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0" }, 845 | { file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010" }, 846 | ] 847 | nvidia-cublas-cu12 = [ 848 | { file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728" }, 849 | { file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906" }, 850 | ] 851 | nvidia-cuda-cupti-cu12 = [ 852 | { file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e" }, 853 | { file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4" }, 854 | ] 855 | nvidia-cuda-nvrtc-cu12 = [ 856 | { file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2" }, 857 | { file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed" }, 858 | ] 859 | nvidia-cuda-runtime-cu12 = [ 860 | { file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40" }, 861 | { file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344" }, 862 | ] 863 | nvidia-cudnn-cu12 = [ 864 | { file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9" }, 865 | ] 866 | nvidia-cufft-cu12 = [ 867 | { file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56" }, 868 | { file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253" }, 869 | ] 870 | nvidia-curand-cu12 = [ 871 | { file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0" }, 872 | { file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a" }, 873 | ] 874 | nvidia-cusolver-cu12 = [ 875 | { file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd" }, 876 | { file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5" }, 877 | ] 878 | nvidia-cusparse-cu12 = [ 879 | { file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c" }, 880 | { file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a" }, 881 | ] 882 | nvidia-nccl-cu12 = [ 883 | { file = "nvidia_nccl_cu12-2.19.3-py3-none-manylinux1_x86_64.whl", hash = "sha256:a9734707a2c96443331c1e48c717024aa6678a0e2a4cb66b2c364d18cee6b48d" }, 884 | ] 885 | nvidia-nvjitlink-cu12 = [ 886 | { file = "nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57" }, 887 | { file = "nvidia_nvjitlink_cu12-12.4.127-py3-none-win_amd64.whl", hash = "sha256:fd9020c501d27d135f983c6d3e244b197a7ccad769e34df53a42e276b0e25fa1" }, 888 | ] 889 | nvidia-nvtx-cu12 = [ 890 | { file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5" }, 891 | { file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82" }, 892 | ] 893 | opencv-python = [ 894 | { file = "opencv-python-4.9.0.80.tar.gz", hash = "sha256:1a9f0e6267de3a1a1db0c54213d022c7c8b5b9ca4b580e80bdc58516c922c9e1" }, 895 | { file = "opencv_python-4.9.0.80-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:7e5f7aa4486651a6ebfa8ed4b594b65bd2d2f41beeb4241a3e4b1b85acbbbadb" }, 896 | { file = "opencv_python-4.9.0.80-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:71dfb9555ccccdd77305fc3dcca5897fbf0cf28b297c51ee55e079c065d812a3" }, 897 | { file = "opencv_python-4.9.0.80-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b34a52e9da36dda8c151c6394aed602e4b17fa041df0b9f5b93ae10b0fcca2a" }, 898 | { file = "opencv_python-4.9.0.80-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4088cab82b66a3b37ffc452976b14a3c599269c247895ae9ceb4066d8188a57" }, 899 | { file = "opencv_python-4.9.0.80-cp37-abi3-win32.whl", hash = "sha256:dcf000c36dd1651118a2462257e3a9e76db789a78432e1f303c7bac54f63ef6c" }, 900 | { file = "opencv_python-4.9.0.80-cp37-abi3-win_amd64.whl", hash = "sha256:3f16f08e02b2a2da44259c7cc712e779eff1dd8b55fdb0323e8cab09548086c0" }, 901 | ] 902 | pillow = [ 903 | { file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45" }, 904 | { file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c" }, 905 | { file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf" }, 906 | { file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599" }, 907 | { file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475" }, 908 | { file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf" }, 909 | { file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3" }, 910 | { file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5" }, 911 | { file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2" }, 912 | { file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f" }, 913 | { file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b" }, 914 | { file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795" }, 915 | { file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57" }, 916 | { file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27" }, 917 | { file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994" }, 918 | { file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451" }, 919 | { file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd" }, 920 | { file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad" }, 921 | { file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c" }, 922 | { file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09" }, 923 | { file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d" }, 924 | { file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f" }, 925 | { file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84" }, 926 | { file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19" }, 927 | { file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338" }, 928 | { file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1" }, 929 | { file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462" }, 930 | { file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a" }, 931 | { file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef" }, 932 | { file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3" }, 933 | { file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d" }, 934 | { file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b" }, 935 | { file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a" }, 936 | { file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b" }, 937 | { file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2" }, 938 | { file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa" }, 939 | { file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383" }, 940 | { file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d" }, 941 | { file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd" }, 942 | { file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d" }, 943 | { file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3" }, 944 | { file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b" }, 945 | { file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999" }, 946 | { file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936" }, 947 | { file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002" }, 948 | { file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60" }, 949 | { file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375" }, 950 | { file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57" }, 951 | { file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8" }, 952 | { file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9" }, 953 | { file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb" }, 954 | { file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572" }, 955 | { file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb" }, 956 | { file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f" }, 957 | { file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355" }, 958 | { file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9" }, 959 | { file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2" }, 960 | { file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463" }, 961 | { file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced" }, 962 | { file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3" }, 963 | { file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170" }, 964 | { file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32" }, 965 | { file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828" }, 966 | { file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f" }, 967 | { file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015" }, 968 | { file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5" }, 969 | { file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a" }, 970 | { file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591" }, 971 | { file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d" }, 972 | ] 973 | python-engineio = [ 974 | { file = "python-engineio-4.9.0.tar.gz", hash = "sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7" }, 975 | { file = "python_engineio-4.9.0-py3-none-any.whl", hash = "sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c" }, 976 | ] 977 | python-socketio = [ 978 | { file = "python-socketio-5.11.2.tar.gz", hash = "sha256:ae6a1de5c5209ca859dc574dccc8931c4be17ee003e74ce3b8d1306162bb4a37" }, 979 | { file = "python_socketio-5.11.2-py3-none-any.whl", hash = "sha256:b9f22a8ff762d7a6e123d16a43ddb1a27d50f07c3c88ea999334f2f89b0ad52b" }, 980 | ] 981 | requests = [ 982 | { file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f" }, 983 | { file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" }, 984 | ] 985 | simple-websocket = [ 986 | { file = "simple-websocket-1.0.0.tar.gz", hash = "sha256:17d2c72f4a2bd85174a97e3e4c88b01c40c3f81b7b648b0cc3ce1305968928c8" }, 987 | { file = "simple_websocket-1.0.0-py3-none-any.whl", hash = "sha256:1d5bf585e415eaa2083e2bcf02a3ecf91f9712e7b3e6b9fa0b461ad04e0837bc" }, 988 | ] 989 | sympy = [ 990 | { file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5" }, 991 | { file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8" }, 992 | ] 993 | torch = [ 994 | { file = "torch-2.2.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bc889d311a855dd2dfd164daf8cc903a6b7273a747189cebafdd89106e4ad585" }, 995 | { file = "torch-2.2.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:15dffa4cc3261fa73d02f0ed25f5fa49ecc9e12bf1ae0a4c1e7a88bbfaad9030" }, 996 | { file = "torch-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:11e8fe261233aeabd67696d6b993eeb0896faa175c6b41b9a6c9f0334bdad1c5" }, 997 | { file = "torch-2.2.2-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:b2e2200b245bd9f263a0d41b6a2dab69c4aca635a01b30cca78064b0ef5b109e" }, 998 | { file = "torch-2.2.2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:877b3e6593b5e00b35bbe111b7057464e76a7dd186a287280d941b564b0563c2" }, 999 | { file = "torch-2.2.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:ad4c03b786e074f46606f4151c0a1e3740268bcf29fbd2fdf6666d66341c1dcb" }, 1000 | { file = "torch-2.2.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:32827fa1fbe5da8851686256b4cd94cc7b11be962862c2293811c94eea9457bf" }, 1001 | { file = "torch-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:f9ef0a648310435511e76905f9b89612e45ef2c8b023bee294f5e6f7e73a3e7c" }, 1002 | { file = "torch-2.2.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:95b9b44f3bcebd8b6cd8d37ec802048c872d9c567ba52c894bba90863a439059" }, 1003 | { file = "torch-2.2.2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:49aa4126ede714c5aeef7ae92969b4b0bbe67f19665106463c39f22e0a1860d1" }, 1004 | { file = "torch-2.2.2-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:cf12cdb66c9c940227ad647bc9cf5dba7e8640772ae10dfe7569a0c1e2a28aca" }, 1005 | { file = "torch-2.2.2-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:89ddac2a8c1fb6569b90890955de0c34e1724f87431cacff4c1979b5f769203c" }, 1006 | { file = "torch-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:451331406b760f4b1ab298ddd536486ab3cfb1312614cfe0532133535be60bea" }, 1007 | { file = "torch-2.2.2-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:eb4d6e9d3663e26cd27dc3ad266b34445a16b54908e74725adb241aa56987533" }, 1008 | { file = "torch-2.2.2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:bf9558da7d2bf7463390b3b2a61a6a3dbb0b45b161ee1dd5ec640bf579d479fc" }, 1009 | { file = "torch-2.2.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd2bf7697c9e95fb5d97cc1d525486d8cf11a084c6af1345c2c2c22a6b0029d0" }, 1010 | { file = "torch-2.2.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:b421448d194496e1114d87a8b8d6506bce949544e513742b097e2ab8f7efef32" }, 1011 | { file = "torch-2.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:3dbcd563a9b792161640c0cffe17e3270d85e8f4243b1f1ed19cca43d28d235b" }, 1012 | { file = "torch-2.2.2-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:31f4310210e7dda49f1fb52b0ec9e59382cfcb938693f6d5378f25b43d7c1d29" }, 1013 | { file = "torch-2.2.2-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:c795feb7e8ce2e0ef63f75f8e1ab52e7fd5e1a4d7d0c31367ade1e3de35c9e95" }, 1014 | { file = "torch-2.2.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:a6e5770d68158d07456bfcb5318b173886f579fdfbf747543901ce718ea94782" }, 1015 | { file = "torch-2.2.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:67dcd726edff108e2cd6c51ff0e416fd260c869904de95750e80051358680d24" }, 1016 | { file = "torch-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:539d5ef6c4ce15bd3bd47a7b4a6e7c10d49d4d21c0baaa87c7d2ef8698632dfb" }, 1017 | { file = "torch-2.2.2-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:dff696de90d6f6d1e8200e9892861fd4677306d0ef604cb18f2134186f719f82" }, 1018 | { file = "torch-2.2.2-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:3a4dd910663fd7a124c056c878a52c2b0be4a5a424188058fe97109d4436ee42" }, 1019 | ] 1020 | torchvision = [ 1021 | { file = "torchvision-0.17.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:1f2910fe3c21ad6875b2720d46fad835b2e4b336e9553d31ca364d24c90b1d4f" }, 1022 | { file = "torchvision-0.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ecc1c503fa8a54fbab777e06a7c228032b8ab78efebf35b28bc8f22f544f51f1" }, 1023 | { file = "torchvision-0.17.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:f400145fc108833e7c2fc28486a04989ca742146d7a2a2cc48878ebbb40cdbbd" }, 1024 | { file = "torchvision-0.17.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:e9e4bed404af33dfc92eecc2b513d21ddc4c242a7fd8708b3b09d3a26aa6f444" }, 1025 | { file = "torchvision-0.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:ba2e62f233eab3d42b648c122a3a29c47cc108ca314dfd5cbb59cd3a143fd623" }, 1026 | { file = "torchvision-0.17.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:9b83e55ee7d0a1704f52b9c0ac87388e7a6d1d98a6bde7b0b35f9ab54d7bda54" }, 1027 | { file = "torchvision-0.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e031004a1bc432c980a7bd642f6c189a3efc316e423fc30b5569837166a4e28d" }, 1028 | { file = "torchvision-0.17.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:3bbc24b7713e8f22766992562547d8b4b10001208d372fe599255af84bfd1a69" }, 1029 | { file = "torchvision-0.17.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:833fd2e4216ced924c8aca0525733fe727f9a1af66dfad7c5be7257e97c39678" }, 1030 | { file = "torchvision-0.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:6835897df852fad1015e6a106c167c83848114cbcc7d86112384a973404e4431" }, 1031 | { file = "torchvision-0.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:14fd1d4a033c325bdba2d03a69c3450cab6d3a625f85cc375781d9237ca5d04d" }, 1032 | { file = "torchvision-0.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9c3acbebbe379af112b62b535820174277b1f3eed30df264a4e458d58ee4e5b2" }, 1033 | { file = "torchvision-0.17.2-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:77d680adf6ce367166a186d2c7fda3a73807ab9a03b2c31a03fa8812c8c5335b" }, 1034 | { file = "torchvision-0.17.2-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:f1c9ab3152cfb27f83aca072cac93a3a4c4e4ab0261cf0f2d516b9868a4e96f3" }, 1035 | { file = "torchvision-0.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:3f784381419f3ed3f2ec2aa42fb4aeec5bf4135e298d1631e41c926e6f1a0dff" }, 1036 | { file = "torchvision-0.17.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:b83aac8d78f48981146d582168d75b6c947cfb0a7693f76e219f1926f6e595a3" }, 1037 | { file = "torchvision-0.17.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1ece40557e122d79975860a005aa7e2a9e2e6c350a03e78a00ec1450083312fd" }, 1038 | { file = "torchvision-0.17.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:32dbeba3987e20f2dc1bce8d1504139fff582898346dfe8ad98d649f97ca78fa" }, 1039 | { file = "torchvision-0.17.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:35ba5c1600c3203549d2316422a659bd20c0cfda1b6085eec94fb9f35f55ca43" }, 1040 | { file = "torchvision-0.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:2f69570f50b1d195e51bc03feffb7b7728207bc36efcfb1f0813712b2379d881" }, 1041 | { file = "torchvision-0.17.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:4868bbfa55758c8107e69a0e7dd5e77b89056035cd38b767ad5b98cdb71c0f0d" }, 1042 | { file = "torchvision-0.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:efd6d0dd0668e15d01a2cffadc74068433b32cbcf5692e0c4aa15fc5cb250ce7" }, 1043 | { file = "torchvision-0.17.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7dc85b397f6c6d9ef12716ce0d6e11ac2b803f5cccff6fe3966db248e7774478" }, 1044 | { file = "torchvision-0.17.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d506854c5acd69b20a8b6641f01fe841685a21c5406b56813184f1c9fc94279e" }, 1045 | { file = "torchvision-0.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:067095e87a020a7a251ac1d38483aa591c5ccb81e815527c54db88a982fc9267" }, 1046 | ] 1047 | triton = [ 1048 | { file = "triton-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2294514340cfe4e8f4f9e5c66c702744c4a117d25e618bd08469d0bfed1e2e5" }, 1049 | { file = "triton-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da58a152bddb62cafa9a857dd2bc1f886dbf9f9c90a2b5da82157cd2b34392b0" }, 1050 | { file = "triton-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af58716e721460a61886668b205963dc4d1e4ac20508cc3f623aef0d70283d5" }, 1051 | { file = "triton-2.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8fe46d3ab94a8103e291bd44c741cc294b91d1d81c1a2888254cbf7ff846dab" }, 1052 | { file = "triton-2.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8ce26093e539d727e7cf6f6f0d932b1ab0574dc02567e684377630d86723ace" }, 1053 | { file = "triton-2.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:227cc6f357c5efcb357f3867ac2a8e7ecea2298cd4606a8ba1e931d1d5a947df" }, 1054 | ] 1055 | typing-extensions = [ 1056 | { file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" }, 1057 | { file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0" }, 1058 | ] 1059 | urllib3 = [ 1060 | { file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d" }, 1061 | { file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" }, 1062 | ] 1063 | websocket-client = [ 1064 | { file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6" }, 1065 | { file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588" }, 1066 | ] 1067 | werkzeug = [ 1068 | { file = "werkzeug-3.0.2-py3-none-any.whl", hash = "sha256:3aac3f5da756f93030740bc235d3e09449efcf65f2f55e3602e1d851b8f48795" }, 1069 | { file = "werkzeug-3.0.2.tar.gz", hash = "sha256:e39b645a6ac92822588e7b39a692e7828724ceae0b0d702ef96701f90e70128d" }, 1070 | ] 1071 | wsproto = [ 1072 | { file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" }, 1073 | { file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065" }, 1074 | ] 1075 | --------------------------------------------------------------------------------