├── tests ├── .gitignore ├── data │ └── images │ │ ├── faces.jpg │ │ └── kate_siegel.jpg └── test_code_design.rs ├── .gitignore ├── python ├── Justfile ├── Cargo.toml ├── pyproject.toml ├── tests │ └── test_api.py ├── .gitignore ├── samples │ ├── detect_faces.py │ └── camera.py ├── src │ └── lib.rs └── Cargo.lock ├── Justfile ├── src ├── ort.rs ├── lib.rs ├── testing.rs ├── detection.rs ├── viz.rs ├── imaging.rs ├── priorboxes.rs ├── nms.rs ├── model_repository.rs ├── builder.rs ├── rect.rs ├── blazeface.rs └── mtcnn.rs ├── cspell.config.yaml ├── Cargo.toml ├── LICENSE ├── .github └── workflows │ ├── CI.yml │ └── python-CI.yml ├── benches └── detectors.rs ├── README.md └── Cargo.lock /tests/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .envrc 3 | *.onnx 4 | .vscode 5 | -------------------------------------------------------------------------------- /tests/data/images/faces.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustybuilder/rust-faces/HEAD/tests/data/images/faces.jpg -------------------------------------------------------------------------------- /tests/data/images/kate_siegel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustybuilder/rust-faces/HEAD/tests/data/images/kate_siegel.jpg -------------------------------------------------------------------------------- /python/Justfile: -------------------------------------------------------------------------------- 1 | fmt: 2 | cargo fmt --verbose --all -- --check 3 | 4 | clippy: 5 | cargo clippy --verbose --all-targets --all-features -- -D warnings 6 | -------------------------------------------------------------------------------- /Justfile: -------------------------------------------------------------------------------- 1 | test: 2 | cargo test --verbose --release --all-features 3 | 4 | fmt: 5 | cargo fmt --verbose --all -- --check 6 | 7 | clippy: 8 | cargo clippy --verbose --all-targets --all-features -- -D warnings -------------------------------------------------------------------------------- /src/ort.rs: -------------------------------------------------------------------------------- 1 | use ort::OrtError; 2 | 3 | use crate::detection::RustFacesError; 4 | 5 | impl From for RustFacesError { 6 | fn from(err: OrtError) -> Self { 7 | RustFacesError::InferenceError(err.to_string()) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /python/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "py_rust_faces" 3 | version = "0.3.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | name = "py_rust_faces" 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | image = "0.24.6" 12 | numpy = "0.19.0" 13 | pyo3 = "0.19.0" 14 | rust-faces = {path = ".." } 15 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | version: "0.2" 2 | ignorePaths: [] 3 | dictionaryDefinitions: [] 4 | dictionaries: [] 5 | words: 6 | - blazeface 7 | - curr 8 | - iproduct 9 | - itertools 10 | - mtcnn 11 | - onet 12 | - Onnx 13 | - optmized 14 | - PNET 15 | - priorboxes 16 | - rnet 17 | - rstest 18 | - thiserror 19 | ignoreWords: [] 20 | import: [] 21 | -------------------------------------------------------------------------------- /python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.1,<2.0", "numpy"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "py_rust_faces" 7 | requires-python = ">=3.7" 8 | classifiers = [ 9 | "Programming Language :: Rust", 10 | "Programming Language :: Python :: Implementation :: CPython", 11 | "Programming Language :: Python :: Implementation :: PyPy", 12 | ] 13 | 14 | 15 | [tool.maturin] 16 | features = ["pyo3/extension-module"] 17 | 18 | [project.optional-dependencies] 19 | dev = [ 20 | "pylint ~=2.17.4", 21 | "black ~=23.3.0", 22 | "pytest ~=7.4.0" 23 | ] 24 | test = [ 25 | "pytest-cov ~=3.0.0", 26 | ] 27 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod rect; 2 | pub use rect::Rect; 3 | 4 | mod detection; 5 | pub use detection::{Face, FaceDetector, RustFacesError, RustFacesResult}; 6 | 7 | mod ort; 8 | 9 | mod nms; 10 | pub use nms::Nms; 11 | 12 | mod imaging; 13 | pub use imaging::{ToArray3, ToRgb8}; 14 | 15 | #[cfg(test)] 16 | pub mod testing; 17 | 18 | pub mod priorboxes; 19 | 20 | mod blazeface; 21 | pub use blazeface::{BlazeFace, BlazeFaceParams}; 22 | 23 | mod mtcnn; 24 | pub use mtcnn::{MtCnn, MtCnnParams}; 25 | 26 | mod builder; 27 | 28 | #[cfg(feature = "viz")] 29 | pub mod viz; 30 | 31 | pub use builder::{FaceDetection, FaceDetectorBuilder, InferParams, Provider}; 32 | 33 | mod model_repository; 34 | -------------------------------------------------------------------------------- /src/testing.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use image::RgbImage; 4 | use ndarray::Array3; 5 | use rstest::fixture; 6 | 7 | use crate::imaging::ToArray3; 8 | 9 | #[fixture] 10 | pub fn sample_array_image() -> Array3 { 11 | image::io::Reader::open("tests/data/images/faces.jpg") 12 | .unwrap() 13 | .decode() 14 | .unwrap() 15 | .into_rgb8() 16 | .into_array3() 17 | } 18 | 19 | #[fixture] 20 | pub fn sample_image() -> RgbImage { 21 | image::io::Reader::open("tests/data/images/kate_siegel.jpg") 22 | .unwrap() 23 | .decode() 24 | .unwrap() 25 | .into_rgb8() 26 | } 27 | 28 | #[fixture] 29 | pub fn output_dir() -> PathBuf { 30 | let output_path = PathBuf::from("tests/output"); 31 | std::fs::create_dir_all(output_path.clone()).expect("Can't create output directory"); 32 | output_path 33 | } 34 | -------------------------------------------------------------------------------- /python/tests/test_api.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import numpy as np 4 | import pytest 5 | from PIL import Image 6 | 7 | import py_rust_faces as prf 8 | 9 | 10 | @pytest.fixture() 11 | def sample_image(): 12 | return np.array( 13 | Image.open(Path(__file__).absolute().parents[2] / "tests/data/images/faces.jpg") 14 | ) 15 | 16 | 17 | def test_blazeface(sample_image): 18 | detector = prf.blazeface(prf.BlazeFace.Net640, infer_provider=prf.InferProvider.OrtCpu) 19 | faces, scores, landmarks = detector.detect(sample_image) 20 | assert faces.shape == (5, 4) 21 | assert scores.shape == (5,) 22 | assert landmarks.shape == (5, 5, 2) 23 | 24 | def test_mtcnn(sample_image): 25 | detector = prf.mtcnn(infer_provider=prf.InferProvider.OrtCpu) 26 | faces, scores, landmarks = detector.detect(sample_image) 27 | assert faces.shape == (5, 4) 28 | assert scores.shape == (5,) 29 | assert landmarks.shape == (5, 5, 2) 30 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-faces" 3 | version = "1.0.0" 4 | edition = "2021" 5 | authors = ["Rusty Builder "] 6 | description = "A Rust library for face detection" 7 | license = "MIT" 8 | repository = "https://github.com/rustybuilder/rust-faces" 9 | readme = "README.md" 10 | 11 | [dependencies] 12 | image = "0.24.6" 13 | ndarray = "0.15.6" 14 | ort = { version = "1.15.2", features = ["load-dynamic"] } 15 | nshare = { version = "0.9.0", features = ["ndarray"] } 16 | imageproc = { version = "0.23.0", optional = true } 17 | reqwest = { version = "0.11.18", features = ["blocking"] } 18 | home = "0.5.5" 19 | thiserror = "1.0.40" 20 | itertools = "0.11.0" 21 | indicatif = "0.17.5" 22 | 23 | [features] 24 | default = [] 25 | viz = ["dep:imageproc"] 26 | 27 | [dev-dependencies] 28 | rstest = "0.17.0" 29 | criterion = { version = "0.4", features = ["html_reports"] } 30 | 31 | [[test]] 32 | name = "test_code_design" 33 | path = "tests/test_code_design.rs" 34 | 35 | [[bench]] 36 | name = "detectors" 37 | harness = false 38 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | .pytest_cache/ 6 | *.py[cod] 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | .venv/ 14 | env/ 15 | bin/ 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | include/ 26 | man/ 27 | venv/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | pip-selfcheck.json 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | 45 | # Translations 46 | *.mo 47 | 48 | # Mr Developer 49 | .mr.developer.cfg 50 | .project 51 | .pydevproject 52 | 53 | # Rope 54 | .ropeproject 55 | 56 | # Django stuff: 57 | *.log 58 | *.pot 59 | 60 | .DS_Store 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyCharm 66 | .idea/ 67 | 68 | # VSCode 69 | .vscode/ 70 | 71 | # Pyenv 72 | .python-version -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Rusty Builder Indies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/test_code_design.rs: -------------------------------------------------------------------------------- 1 | use rust_faces::{ 2 | viz, BlazeFaceParams, FaceDetection, FaceDetectorBuilder, InferParams, Provider, ToArray3, 3 | ToRgb8, 4 | }; 5 | 6 | #[test] 7 | pub fn main() { 8 | let face_detector = 9 | FaceDetectorBuilder::new(FaceDetection::BlazeFace640(BlazeFaceParams::default())) 10 | .download() 11 | .infer_params(InferParams { 12 | provider: Provider::OrtCpu, 13 | intra_threads: Some(5), 14 | ..Default::default() 15 | }) 16 | .build() 17 | .expect("Fail to load the face detector."); 18 | 19 | let image = image::open("tests/data/images/faces.jpg") 20 | .expect("Can't open test image.") 21 | .into_rgb8() 22 | .into_array3(); 23 | let faces = face_detector.detect(image.view().into_dyn()).unwrap(); 24 | 25 | let mut image = image.to_rgb8(); 26 | viz::draw_faces(&mut image, faces); 27 | std::fs::create_dir_all("tests/output").expect("Can't create test output dir."); 28 | image 29 | .save("tests/output/test_design.jpg") 30 | .expect("Can't save test image."); 31 | } 32 | -------------------------------------------------------------------------------- /python/samples/detect_faces.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | from PIL import Image 6 | import matplotlib.pyplot as plt 7 | from matplotlib.patches import Rectangle 8 | 9 | import py_rust_faces as prf 10 | 11 | 12 | def main(): 13 | parser = argparse.ArgumentParser() 14 | parser.add_argument( 15 | "--image", 16 | default=Path(__file__).absolute().parents[2] / "tests/data/images/faces.jpg", 17 | ) 18 | args = parser.parse_args() 19 | detector = prf.build_detector(prf.FaceDetection.BlazeFace640) 20 | image = np.array(Image.open(args.image)) 21 | rects, _confidences, landmarks = detector.detect(image) 22 | 23 | plt.imshow(image) 24 | for rect, lms in zip(rects, landmarks): 25 | plt.gca().add_patch( 26 | Rectangle( 27 | (rect[0], rect[1]), 28 | rect[2], 29 | rect[3], 30 | edgecolor="red", 31 | facecolor="none", 32 | lw=2, 33 | ) 34 | ) 35 | plt.plot(lms[:, 0], lms[:, 1], "ro") 36 | 37 | plt.show() 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /src/detection.rs: -------------------------------------------------------------------------------- 1 | use crate::Rect; 2 | use ndarray::ArrayViewD; 3 | use thiserror::Error; 4 | 5 | /// Error type for RustFaces. 6 | #[derive(Error, Debug)] 7 | pub enum RustFacesError { 8 | /// IO errors. 9 | #[error("IO error: {0}")] 10 | IoError(std::io::Error), 11 | /// Errors related to image processing 12 | #[error("Image error: {0}")] 13 | ImageError(String), 14 | /// Errors related to inference engine (e.g. ONNX runtime) 15 | #[error("Inference error: {0}")] 16 | InferenceError(String), 17 | /// Other errors. 18 | #[error("Other error: {0}")] 19 | Other(String), 20 | } 21 | 22 | impl From for RustFacesError { 23 | fn from(err: std::io::Error) -> Self { 24 | RustFacesError::IoError(err) 25 | } 26 | } 27 | 28 | pub type RustFacesResult = Result; 29 | 30 | /// Face detection result. 31 | #[derive(Debug, Clone)] 32 | pub struct Face { 33 | /// Face's bounding rectangle. 34 | pub rect: Rect, 35 | /// Confidence of the detection. 36 | pub confidence: f32, 37 | /// Landmarks of the face. 38 | pub landmarks: Option>, 39 | } 40 | 41 | /// Face detector trait. 42 | pub trait FaceDetector: Sync + Send { 43 | /// Detects faces in the given image. 44 | /// 45 | /// # Arguments 46 | /// 47 | /// * `image` - Image to detect faces in. Should be in RGB format. 48 | fn detect(&self, image: ArrayViewD) -> RustFacesResult>; 49 | } 50 | -------------------------------------------------------------------------------- /src/viz.rs: -------------------------------------------------------------------------------- 1 | use image::{GenericImage, Rgb}; 2 | 3 | use crate::{Face, Rect}; 4 | 5 | impl From for imageproc::rect::Rect { 6 | fn from(rect: Rect) -> Self { 7 | imageproc::rect::Rect::at(rect.x as i32, rect.y as i32) 8 | .of_size(rect.width as u32, rect.height as u32) 9 | } 10 | } 11 | 12 | /// Draws faces on the image. 13 | pub fn draw_faces(image: &mut I, faces: Vec) 14 | where 15 | I: GenericImage>, 16 | { 17 | for face in faces { 18 | imageproc::drawing::draw_hollow_rect_mut(image, face.rect.into(), Rgb([0, 255, 0])); 19 | for lm in face.landmarks.unwrap_or_default() { 20 | imageproc::drawing::draw_filled_circle_mut( 21 | image, 22 | (lm.0 as i32, lm.1 as i32), 23 | 2, 24 | Rgb([255, 0, 0]), 25 | ); 26 | } 27 | } 28 | } 29 | 30 | #[cfg(test)] 31 | mod tests { 32 | use std::path::Path; 33 | 34 | use super::*; 35 | use image::ImageBuffer; 36 | 37 | #[test] 38 | fn test_draw_faces() { 39 | let mut image = ImageBuffer::new(100, 100); 40 | let faces = vec![Face { 41 | rect: Rect { 42 | x: 10.0, 43 | y: 10.0, 44 | width: 10.0, 45 | height: 10.0, 46 | }, 47 | confidence: 0.9, 48 | landmarks: None, 49 | }]; 50 | draw_faces(&mut image, faces); 51 | std::fs::create_dir_all(Path::new("tests/output")).expect("Failed to create output dir."); 52 | 53 | image.save("tests/output/test_draw_faces.png").unwrap(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build-check: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Build 18 | run: cargo build --verbose --release 19 | - name: Run fmt 20 | run: cargo fmt --verbose --all -- --check 21 | - name: Run clippy 22 | run: cargo clippy --verbose --all-targets --all-features -- -D warnings 23 | - name: Run tests 24 | run: cargo test --verbose --release --features viz 25 | 26 | windows: 27 | runs-on: windows-latest 28 | strategy: 29 | matrix: 30 | target: [x64] 31 | steps: 32 | - uses: actions/checkout@v3 33 | - name: Download Onnx Runtime 34 | shell: pwsh 35 | run: | 36 | Invoke-WebRequest -Uri https://github.com/microsoft/onnxruntime/releases/download/v1.15.1/onnxruntime-win-x64-1.15.1.zip -OutFile onnxruntime-win-x64-1.15.1.zip 37 | Expand-Archive -Path onnxruntime-win-x64-1.15.1.zip -DestinationPath . 38 | - uses: actions-rs/toolchain@v1 39 | with: 40 | toolchain: stable 41 | override: true 42 | - name: Build 43 | run: cargo build --verbose --release 44 | - name: Copy Onnx Runtime 45 | run: | 46 | cp -r onnxruntime-win-x64-1.15.1/lib/*.dll target/release/deps 47 | - name: test 48 | run: cargo test --verbose --release --features viz 49 | 50 | macos: 51 | runs-on: macos-latest 52 | strategy: 53 | matrix: 54 | target: [x86_64, aarch64] 55 | steps: 56 | - uses: actions/checkout@v3 57 | - uses: actions-rs/toolchain@v1 58 | with: 59 | toolchain: stable 60 | override: true 61 | - name: Build 62 | run: cargo build --verbose --release 63 | - name: test 64 | run: cargo test --verbose --release --features viz 65 | -------------------------------------------------------------------------------- /benches/detectors.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Criterion}; 2 | use rust_faces::{ 3 | BlazeFaceParams, FaceDetection, FaceDetectorBuilder, InferParams, MtCnnParams, Provider, 4 | ToArray3, 5 | }; 6 | 7 | fn criterion_benchmark(c: &mut Criterion) { 8 | let image = image::open("tests/data/images/faces.jpg") 9 | .expect("Can't open test image.") 10 | .into_rgb8() 11 | .into_array3(); 12 | 13 | for (name, detection, provider) in vec![ 14 | ( 15 | "blazeface640_cpu", 16 | FaceDetection::BlazeFace640(BlazeFaceParams::default()), 17 | Provider::OrtCpu, 18 | ), 19 | ( 20 | "blazeface640_gpu", 21 | FaceDetection::BlazeFace640(BlazeFaceParams::default()), 22 | Provider::OrtCuda(0), 23 | ), 24 | ( 25 | "blazeface320_cpu", 26 | FaceDetection::BlazeFace320(BlazeFaceParams::default()), 27 | Provider::OrtCpu, 28 | ), 29 | ( 30 | "blazeface320_gpu", 31 | FaceDetection::BlazeFace320(BlazeFaceParams::default()), 32 | Provider::OrtCuda(0), 33 | ), 34 | ( 35 | "mtcnn_cpu", 36 | FaceDetection::MtCnn(MtCnnParams::default()), 37 | Provider::OrtCpu, 38 | ), 39 | ( 40 | "mtcnn_gpu", 41 | FaceDetection::MtCnn(MtCnnParams::default()), 42 | Provider::OrtCuda(0), 43 | ), 44 | ] { 45 | let face_detector = FaceDetectorBuilder::new(detection) 46 | .download() 47 | .infer_params(InferParams { 48 | provider, 49 | ..Default::default() 50 | }) 51 | .build() 52 | .expect("Fail to load the face detector."); 53 | c.bench_function(name, |b| { 54 | b.iter(|| face_detector.detect(image.view().into_dyn()).unwrap()) 55 | }); 56 | } 57 | } 58 | 59 | criterion_group!(benches, criterion_benchmark); 60 | criterion_main!(benches); 61 | -------------------------------------------------------------------------------- /python/samples/camera.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | 4 | import cv2 5 | import numpy as np 6 | 7 | import py_rust_faces as prf 8 | 9 | 10 | def main(): 11 | parser = argparse.ArgumentParser() 12 | parser.add_argument( 13 | "--camera", 14 | "-c", 15 | default=0, 16 | type=int, 17 | ) 18 | parser.add_argument( 19 | "--detector", 20 | "-d", 21 | choices=["blazeface320", "blazeface640", "mtcnn"], 22 | default="mtcnn", 23 | ) 24 | parser.add_argument( 25 | "--provider", "-p", choices=["cpu", "cuda", "vino"], default="cpu" 26 | ) 27 | args = parser.parse_args() 28 | 29 | infer_provider = prf.InferProvider.OrtCpu 30 | if args.provider == "cuda": 31 | infer_provider = prf.InferProvider.OrtCuda 32 | elif args.provider == "vino": 33 | infer_provider = prf.InferProvider.OrtVino 34 | 35 | if args.detector == "blazeface320": 36 | detector = prf.blazeface(prf.BlazeFace.Net320, infer_provider=infer_provider) 37 | elif args.detector == "blazeface640": 38 | detector = prf.blazeface(prf.BlazeFace.Net640, infer_provider=infer_provider) 39 | else: 40 | detector = prf.mtcnn(infer_provider=infer_provider) 41 | 42 | capture = cv2.VideoCapture(args.camera) 43 | 44 | while True: 45 | ret, frame = capture.read() 46 | if not ret: 47 | break 48 | 49 | frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 50 | rects, _confidences, landmarks = detector.detect(frame_rgb) 51 | rects = rects.astype(np.int32) 52 | landmarks = landmarks.astype(np.int32) 53 | for r, landmarks in zip(rects, landmarks): 54 | cv2.rectangle( 55 | frame, (r[0], r[1]), (r[0] + r[2], r[1] + r[3]), (0, 0, 255), 2 56 | ) 57 | 58 | for lm in landmarks: 59 | cv2.circle(frame, (lm[0], lm[1]), 2, (0, 255, 0), 2) 60 | 61 | cv2.imshow("Faces", frame) 62 | key = chr(cv2.waitKey(1) & 0xFF) 63 | 64 | if key == "q": 65 | break 66 | 67 | 68 | if __name__ == "__main__": 69 | main() 70 | -------------------------------------------------------------------------------- /.github/workflows/python-CI.yml: -------------------------------------------------------------------------------- 1 | # This file is autogenerated by maturin v1.1.0 2 | # To update, run 3 | # 4 | # maturin generate-ci github 5 | # 6 | name: Python 7 | 8 | on: 9 | push: 10 | branches: 11 | - main 12 | - master 13 | tags: 14 | - '*' 15 | pull_request: 16 | workflow_dispatch: 17 | 18 | permissions: 19 | contents: read 20 | 21 | jobs: 22 | windows: 23 | runs-on: windows-latest 24 | strategy: 25 | matrix: 26 | target: [x64] 27 | steps: 28 | - uses: actions/checkout@v3 29 | - uses: actions/setup-python@v4 30 | with: 31 | python-version: '3.10' 32 | architecture: ${{ matrix.target }} 33 | - name: Build wheels 34 | uses: PyO3/maturin-action@v1 35 | with: 36 | target: ${{ matrix.target }} 37 | args: --release --out dist --find-interpreter 38 | sccache: 'true' 39 | working-directory: python 40 | - name: Upload wheels 41 | uses: actions/upload-artifact@v3 42 | with: 43 | name: wheels 44 | path: python/dist 45 | 46 | macos: 47 | runs-on: macos-latest 48 | strategy: 49 | matrix: 50 | target: [x86_64, aarch64] 51 | steps: 52 | - uses: actions/checkout@v3 53 | - uses: actions/setup-python@v4 54 | with: 55 | python-version: '3.10' 56 | - name: Build wheels 57 | uses: PyO3/maturin-action@v1 58 | with: 59 | target: ${{ matrix.target }} 60 | args: --release --out dist --find-interpreter 61 | sccache: 'true' 62 | working-directory: python 63 | - name: Upload wheels 64 | uses: actions/upload-artifact@v3 65 | with: 66 | name: wheels 67 | path: python/dist 68 | 69 | sdist: 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: actions/checkout@v3 73 | - name: Build sdist 74 | uses: PyO3/maturin-action@v1 75 | with: 76 | command: sdist 77 | args: --out dist 78 | working-directory: python 79 | - name: Upload sdist 80 | uses: actions/upload-artifact@v3 81 | with: 82 | name: wheels 83 | path: python/dist 84 | -------------------------------------------------------------------------------- /src/imaging.rs: -------------------------------------------------------------------------------- 1 | use image::{flat::SampleLayout, GenericImageView, ImageBuffer, Pixel}; 2 | use ndarray::{Array3, ShapeBuilder}; 3 | 4 | pub fn make_border( 5 | image: &I, 6 | top: u32, 7 | bottom: u32, 8 | left: u32, 9 | right: u32, 10 | color: I::Pixel, 11 | ) -> ImageBuffer::Subpixel>> 12 | where 13 | I::Pixel: 'static, 14 | ::Subpixel: 'static, 15 | { 16 | let (width, height) = image.dimensions(); 17 | 18 | let mut new_image = ImageBuffer::new(width + left + right, height + top + bottom); 19 | 20 | for (x, y, pixel) in new_image.enumerate_pixels_mut() { 21 | if x < left || x >= width + left || y < top || y >= height + top { 22 | *pixel = color; 23 | } else { 24 | *pixel = image.get_pixel(x - left, y - top); 25 | } 26 | } 27 | new_image 28 | } 29 | 30 | pub trait ToRgb8 { 31 | fn to_rgb8(&self) -> ImageBuffer, Vec>; 32 | } 33 | 34 | impl ToRgb8 for Array3 { 35 | fn to_rgb8(&self) -> ImageBuffer, Vec> { 36 | let (height, width, _) = self.dim(); 37 | let mut image = ImageBuffer::new(width as u32, height as u32); 38 | for (x, y, pixel) in image.enumerate_pixels_mut() { 39 | let r = self[[y as usize, x as usize, 0]]; 40 | let g = self[[y as usize, x as usize, 1]]; 41 | let b = self[[y as usize, x as usize, 2]]; 42 | *pixel = image::Rgb([r, g, b]); 43 | } 44 | image 45 | } 46 | } 47 | 48 | /// Uses this trait to convert an image to an ndarray::Array3. 49 | /// Note that conversion must keep HxWxC order. 50 | pub trait ToArray3 { 51 | type Out; 52 | 53 | fn into_array3(self) -> Self::Out; 54 | } 55 | 56 | impl

ToArray3 for ImageBuffer> 57 | where 58 | P: Pixel + 'static, 59 | { 60 | type Out = Array3; 61 | 62 | fn into_array3(self) -> Self::Out { 63 | let SampleLayout { 64 | channels, 65 | channel_stride, 66 | height, 67 | height_stride, 68 | width, 69 | width_stride, 70 | } = self.sample_layout(); 71 | let shape = (height as usize, width as usize, channels as usize); 72 | let strides = (height_stride, width_stride, channel_stride); 73 | Array3::from_shape_vec(shape.strides(strides), self.into_raw()).unwrap() 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/priorboxes.rs: -------------------------------------------------------------------------------- 1 | use itertools::iproduct; 2 | 3 | use crate::Rect; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct PriorBoxesParams { 7 | min_sizes: Vec>, 8 | steps: Vec, 9 | variance: (f32, f32), 10 | } 11 | 12 | impl Default for PriorBoxesParams { 13 | fn default() -> Self { 14 | Self { 15 | min_sizes: vec![vec![8, 11], vec![14, 19, 26, 38, 64, 149]], 16 | steps: vec![8, 16], 17 | variance: (0.1, 0.2), 18 | } 19 | } 20 | } 21 | 22 | pub struct PriorBoxes { 23 | pub anchors: Vec<(f32, f32, f32, f32)>, 24 | variances: (f32, f32), 25 | } 26 | 27 | impl PriorBoxes { 28 | pub fn new(params: &PriorBoxesParams, image_size: (usize, usize)) -> Self { 29 | let feature_map_sizes: Vec<(usize, usize)> = params 30 | .steps 31 | .iter() 32 | .map(|&step| (image_size.0 / step, image_size.1 / step)) 33 | .collect(); 34 | 35 | let mut anchors = Vec::new(); 36 | 37 | for ((f, min_sizes), step) in feature_map_sizes 38 | .iter() 39 | .zip(params.min_sizes.iter()) 40 | .zip(params.steps.iter()) 41 | { 42 | let step = *step; 43 | for (i, j) in iproduct!(0..f.1, 0..f.0) { 44 | for min_size in min_sizes { 45 | let s_kx = *min_size as f32 / image_size.0 as f32; 46 | let s_ky = *min_size as f32 / image_size.1 as f32; 47 | let cx = (j as f32 + 0.5) * step as f32 / image_size.0 as f32; 48 | let cy = (i as f32 + 0.5) * step as f32 / image_size.1 as f32; 49 | anchors.push((cx, cy, s_kx, s_ky)); 50 | } 51 | } 52 | } 53 | 54 | Self { 55 | anchors, 56 | variances: params.variance, 57 | } 58 | } 59 | 60 | pub fn decode_box(&self, prior: &(f32, f32, f32, f32), pred: &(f32, f32, f32, f32)) -> Rect { 61 | let (anchor_cx, anchor_cy, s_kx, s_ky) = prior; 62 | let (x1, y1, x2, y2) = pred; 63 | 64 | let cx = anchor_cx + x1 * self.variances.0 * s_kx; 65 | let cy = anchor_cy + y1 * self.variances.0 * s_ky; 66 | let width = s_kx * (x2 * self.variances.1).exp(); 67 | let height = s_ky * (y2 * self.variances.1).exp(); 68 | let x_start = cx - width / 2.0; 69 | let y_start = cy - height / 2.0; 70 | Rect::at(x_start, y_start).ending_at(width + x_start, height + y_start) 71 | } 72 | 73 | pub fn decode_landmark( 74 | &self, 75 | prior: &(f32, f32, f32, f32), 76 | landmark: (f32, f32), 77 | ) -> (f32, f32) { 78 | let (anchor_cx, anchor_cy, s_kx, s_ky) = prior; 79 | let (x, y) = landmark; 80 | let x = anchor_cx + x * self.variances.0 * s_kx; 81 | let y = anchor_cy + y * self.variances.0 * s_ky; 82 | (x, y) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/nms.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::Face; 4 | 5 | /// Non-maximum suppression. 6 | #[derive(Copy, Clone, Debug)] 7 | pub struct Nms { 8 | pub iou_threshold: f32, 9 | } 10 | 11 | impl Default for Nms { 12 | fn default() -> Self { 13 | Self { iou_threshold: 0.3 } 14 | } 15 | } 16 | 17 | impl Nms { 18 | /// Suppress non-maxima faces. 19 | /// 20 | /// # Arguments 21 | /// 22 | /// * `faces` - Faces to suppress. 23 | /// 24 | /// # Returns 25 | /// 26 | /// * `Vec` - Suppressed faces. 27 | pub fn suppress_non_maxima(&self, mut faces: Vec) -> Vec { 28 | faces.sort_by(|a, b| a.confidence.partial_cmp(&b.confidence).unwrap()); 29 | 30 | let mut faces_map = HashMap::new(); 31 | faces.iter().rev().enumerate().for_each(|(i, face)| { 32 | faces_map.insert(i, face); 33 | }); 34 | 35 | let mut nms_faces = Vec::with_capacity(faces.len()); 36 | let mut count = 0; 37 | while !faces_map.is_empty() { 38 | if let Some((_, face)) = faces_map.remove_entry(&count) { 39 | nms_faces.push(face.clone()); 40 | //faces_map.retain(|_, face2| face.rect.iou(&face2.rect) < self.iou_threshold); 41 | faces_map.retain(|_, face2| face.rect.iou(&face2.rect) < self.iou_threshold); 42 | } 43 | count += 1; 44 | } 45 | 46 | nms_faces 47 | } 48 | 49 | /// Suppress non-maxima faces. 50 | /// 51 | /// # Arguments 52 | /// 53 | /// * `faces` - Faces to suppress. 54 | /// 55 | /// # Returns 56 | /// 57 | /// * `Vec` - Suppressed faces. 58 | pub fn suppress_non_maxima_min(&self, mut faces: Vec) -> Vec { 59 | faces.sort_by(|a, b| a.confidence.partial_cmp(&b.confidence).unwrap()); 60 | 61 | let mut faces_map = HashMap::new(); 62 | faces.iter().rev().enumerate().for_each(|(i, face)| { 63 | faces_map.insert(i, face); 64 | }); 65 | 66 | let mut nms_faces = Vec::with_capacity(faces.len()); 67 | let mut count = 0; 68 | while !faces_map.is_empty() { 69 | if let Some((_, face)) = faces_map.remove_entry(&count) { 70 | nms_faces.push(face.clone()); 71 | //faces_map.retain(|_, face2| face.rect.iou(&face2.rect) < self.iou_threshold); 72 | faces_map.retain(|_, face2| face.rect.iou_min(&face2.rect) < self.iou_threshold); 73 | } 74 | count += 1; 75 | } 76 | 77 | nms_faces 78 | } 79 | } 80 | 81 | #[cfg(test)] 82 | mod tests { 83 | use rstest::rstest; 84 | 85 | use super::*; 86 | use crate::{Face, Rect}; 87 | 88 | #[rstest] 89 | fn test_nms() { 90 | let nms = Nms::default(); 91 | let faces = vec![ 92 | Face { 93 | rect: Rect { 94 | x: 0.0, 95 | y: 0.0, 96 | width: 1.0, 97 | height: 1.0, 98 | }, 99 | confidence: 0.9, 100 | landmarks: None, 101 | }, 102 | Face { 103 | rect: Rect { 104 | x: 0.0, 105 | y: 0.0, 106 | width: 1.0, 107 | height: 1.0, 108 | }, 109 | confidence: 0.8, 110 | landmarks: None, 111 | }, 112 | Face { 113 | rect: Rect { 114 | x: 0.0, 115 | y: 0.0, 116 | width: 1.0, 117 | height: 1.0, 118 | }, 119 | confidence: 0.7, 120 | landmarks: None, 121 | }, 122 | ]; 123 | 124 | let faces = nms.suppress_non_maxima(faces); 125 | 126 | assert_eq!(faces.len(), 1); 127 | assert_eq!(faces[0].confidence, 0.9); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/model_repository.rs: -------------------------------------------------------------------------------- 1 | use crate::builder::FaceDetection; 2 | use crate::detection::{RustFacesError, RustFacesResult}; 3 | use indicatif::{ProgressBar, ProgressStyle}; 4 | use reqwest::header::{HeaderMap, HeaderValue, ACCEPT}; 5 | use std::fs::File; 6 | use std::io::BufWriter; 7 | use std::path::PathBuf; 8 | use std::time::Duration; 9 | 10 | pub trait ModelRepository { 11 | fn get_model(&self, face_detector: &FaceDetection) -> RustFacesResult>; 12 | } 13 | 14 | fn download_file(url: &str, destination: &str) -> RustFacesResult<()> { 15 | fn get_headers() -> HeaderMap { 16 | let mut headers = HeaderMap::new(); 17 | headers.insert(ACCEPT, HeaderValue::from_static("*/*")); 18 | headers 19 | } 20 | 21 | let pb = ProgressBar::new_spinner(); 22 | pb.enable_steady_tick(Duration::from_millis(120)); 23 | pb.set_style( 24 | ProgressStyle::with_template("{spinner:.blue} {msg}") 25 | .unwrap() 26 | .tick_strings(&[ 27 | "▹▹▹▹▹", 28 | "▸▹▹▹▹", 29 | "▹▸▹▹▹", 30 | "▹▹▸▹▹", 31 | "▹▹▹▸▹", 32 | "▹▹▹▹▸", 33 | "▪▪▪▪▪", 34 | ]), 35 | ); 36 | pb.set_message(format!("Downloading {url}")); 37 | let client = reqwest::blocking::Client::new(); 38 | match client.get(url).headers(get_headers()).send() { 39 | Ok(mut response) => { 40 | if response.status().is_success() { 41 | let file = File::create(destination)?; 42 | let mut writer = BufWriter::new(file); 43 | while let Ok(bytes_read) = response.copy_to(&mut writer) { 44 | if bytes_read == 0 { 45 | break; 46 | } 47 | } 48 | pb.finish_with_message("Done"); 49 | Ok(()) 50 | } else { 51 | pb.finish_with_message("Failed to download file."); 52 | Err(RustFacesError::IoError(std::io::Error::new( 53 | std::io::ErrorKind::Other, 54 | "Failed to download file.", 55 | ))) 56 | } 57 | } 58 | Err(err) => { 59 | pb.finish_with_message("Failed to download file."); 60 | Err(RustFacesError::Other(format!( 61 | "Failed to download file: {}", 62 | err 63 | ))) 64 | } 65 | } 66 | } 67 | 68 | fn get_cache_dir() -> RustFacesResult { 69 | let home_dir = home::home_dir(); 70 | if home_dir.is_none() { 71 | return Err(RustFacesError::Other( 72 | "Failed to get home directory.".to_string(), 73 | )); 74 | } 75 | 76 | let cache_dir = home_dir.unwrap().join(".rust_faces/"); 77 | std::fs::create_dir_all(&cache_dir)?; 78 | Ok(cache_dir) 79 | } 80 | 81 | pub struct GitHubRepository {} 82 | 83 | impl GitHubRepository { 84 | pub fn new() -> GitHubRepository { 85 | GitHubRepository {} 86 | } 87 | } 88 | 89 | impl ModelRepository for GitHubRepository { 90 | fn get_model(&self, face_detector: &FaceDetection) -> RustFacesResult> { 91 | let (urls, filenames) = match face_detector { 92 | FaceDetection::BlazeFace640(_) => ( 93 | ["https://github.com/rustybuilder/model-zoo/raw/main/face-detection/blazefaces-640.onnx"].as_slice(), 94 | ["blazeface-640.onnx"].as_slice(), 95 | ), 96 | FaceDetection::BlazeFace320(_) => ( 97 | ["https://github.com/rustybuilder/model-zoo/raw/main/face-detection/blazeface-320.onnx"].as_slice(), 98 | ["blazeface-320.onnx"].as_slice(), 99 | ), 100 | FaceDetection::MtCnn(_) => ( 101 | ["https://github.com/rustybuilder/model-zoo/raw/main/face-detection/mtcnn-pnet.onnx", 102 | "https://github.com/rustybuilder/model-zoo/raw/main/face-detection/mtcnn-rnet.onnx", 103 | "https://github.com/rustybuilder/model-zoo/raw/main/face-detection/mtcnn-onet.onnx"].as_slice(), 104 | ["mtcnn-pnet.onnx", "mtcnn-rnet.onnx", "mtcnn-onet.onnx"].as_slice(), 105 | ) 106 | }; 107 | 108 | let mut result = Vec::new(); 109 | for (url, filename) in urls.iter().zip(filenames) { 110 | let dest_filepath = get_cache_dir()?.join(filename); 111 | if !dest_filepath.exists() { 112 | download_file(url, dest_filepath.to_str().unwrap())?; 113 | } 114 | result.push(dest_filepath); 115 | } 116 | 117 | Ok(result) 118 | } 119 | } 120 | 121 | #[cfg(test)] 122 | mod tests { 123 | use crate::{ 124 | blazeface::BlazeFaceParams, 125 | builder::FaceDetection, 126 | model_repository::{GitHubRepository, ModelRepository}, 127 | }; 128 | 129 | use super::download_file; 130 | 131 | #[test] 132 | #[ignore] 133 | fn test_download() { 134 | download_file( 135 | "https://github.com/rustybuilder/model-zoo/raw/main/face-detection/blazeface-320.onnx", 136 | "tests/output/sample_download", 137 | ) 138 | .unwrap(); 139 | } 140 | 141 | #[test] 142 | fn test_google_drive_repository() { 143 | let repo = GitHubRepository {}; 144 | let model_path = repo 145 | .get_model(&FaceDetection::BlazeFace640(BlazeFaceParams::default())) 146 | .expect("Failed to get model")[0] 147 | .clone(); 148 | assert!(model_path.exists()); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust Faces - Face Detection Models with Rust Interface 2 | 3 | [![Rust](https://github.com/rustybuilder/rust-faces/actions/workflows/CI.yml/badge.svg)](https://github.com/rustybuilder/rust-faces/actions/workflows/CI.yml) 4 | 5 | [![Python](https://github.com/rustybuilder/rust-faces/actions/workflows/python-CI.yml/badge.svg)](https://github.com/rustybuilder/rust-faces/actions/workflows/python-CI.yml) 6 | 7 | This project aims to provide a Rust interface for multiple state-of-the-art face detection models. 8 | 9 | ## Features 10 | 11 | * Integration of multiple face detection models; 12 | * Rust interface: The core implementation is written in Rust, leveraging its safety, performance, and concurrency features for preprocessing, non-maxima suppression, and other non-neural-network computationally intensive tasks. 13 | * ONNX Runtime inference provided by [Ort](https://github.com/pykeio/ort). 14 | * Language bindings: The project will provide bindings to Python (✔️), C (⚙️), C++ (⚙️), Java (⚙️), and C# (⚙️), enabling more developers with face technologies. 15 | * Easy integration 16 | 17 | ## Supported Face Detection Models 18 | 19 | The project aims to include a selection of popular and high-performing face detection models, such as: 20 | 21 | * [x] [BlazeFace](https://github.com/zineos/blazeface) - BlazeFace640 and BlazeFace320 22 | * [x] MTCNN (Multi-Task Cascaded Convolutional Networks) - Models from [timesler/facenet-pytorch](https://github.com/timesler/facenet-pytorch) 23 | 24 | **Please note that the availability of specific models may vary depending on the licensing terms and open-source availability of the respective models.** 25 | 26 | ## Usage 27 | 28 | Linux Requirements: 29 | 30 | * libssl-dev 31 | * pkg-config 32 | 33 | Ubuntu: `$sudo apt install libssl-dev pkg-config` 34 | 35 | Install the crate: 36 | 37 | ```shell 38 | $ cargo add rust-faces --features viz 39 | ``` 40 | 41 | ```rust 42 | use rust_faces::{ 43 | viz, BlazeFaceParams, FaceDetection, FaceDetectorBuilder, InferParams, Provider, ToArray3, 44 | ToRgb8, 45 | }; 46 | 47 | pub fn main() { 48 | let face_detector = 49 | FaceDetectorBuilder::new(FaceDetection::BlazeFace640(BlazeFaceParams::default())) 50 | .download() 51 | .infer_params(InferParams { 52 | provider: Provider::OrtCpu, 53 | intra_threads: Some(5), 54 | ..Default::default() 55 | }) 56 | .build() 57 | .expect("Fail to load the face detector."); 58 | 59 | let image = image::open("tests/data/images/faces.jpg") 60 | .expect("Can't open test image.") 61 | .into_rgb8() 62 | .into_array3(); 63 | let faces = face_detector.detect(image.view().into_dyn()).unwrap(); 64 | 65 | let mut image = image.to_rgb8(); 66 | viz::draw_faces(&mut image, faces); 67 | std::fs::create_dir_all("tests/output").expect("Can't create test output dir."); 68 | image 69 | .save("tests/output/should_have_smooth_design.jpg") 70 | .expect("Can't save test image."); 71 | } 72 | ``` 73 | 74 | ### Make OnnxRuntime shared library available 75 | 76 | [Linux] If necessary, export your library path to the onnx runtime directory. 77 | 78 | ```shell 79 | $ export LD_LIBRARY_PATH=:$LD_LIBRARY_PATH 80 | ``` 81 | 82 | If you still receive the following error message: 83 | 84 | > PanicException: ort 1.14 is not compatible with the ONNX Runtime binary found at `onnxruntime.dll`; expected GetVersionString to return '1.14.x', but got '1.10.0' 85 | 86 | Try to direct set the environment variable `ORT_DYLIB_PATH`: 87 | 88 | ```bash 89 | # bash 90 | $ export ORT_DYLIB_PATH="/onnxruntime.so" 91 | ``` 92 | 93 | ```powershell 94 | # Powershell 95 | > $env:ORT_DYLIB_PATH="/onnxruntime.dll" 96 | ``` 97 | 98 | More details on the [Ort](https://github.com/pykeio/ort) project. 99 | 100 | ## Python usage 101 | 102 | **Requirements** 103 | 104 | * [Rust](https://www.rust-lang.org/learn/get-started) 105 | * [Onnx Runtime](https://github.com/microsoft/onnxruntime/releases/tag/v1.15.1) - Download one of the releases 106 | 107 | 108 | ```shell 109 | $ pip install -e "git+https://github.com/rustybuilder/rust-faces.git#egg=py-rust-faces&subdirectory=python" --install-option="--release" 110 | ``` 111 | 112 | Usage: 113 | 114 | ```python 115 | import numpy as np 116 | from PIL import Image 117 | import matplotlib.pyplot as plt 118 | from matplotlib.patches import Rectangle 119 | 120 | import py_rust_faces as prf 121 | 122 | detector = prf.blazeface(prf.BlazeFace.Net320) 123 | image = np.array(Image.open(args.image)) 124 | rects, _confidences, _landmarks = detector.detect(image) 125 | plt.imshow(image) 126 | 127 | for rect in rects: 128 | plt.gca().add_patch( 129 | Rectangle( 130 | (rect[0], rect[1]), 131 | rect[2], 132 | rect[3], 133 | edgecolor="red", 134 | facecolor="none", 135 | lw=2, 136 | ) 137 | ) 138 | plt.show() 139 | ``` 140 | 141 | ## Benchmarks 142 | 143 | | Algorithm | [min, mean, max] | 144 | |-------------|-----------------------------------| 145 | | MTCNN (cpu) | [12.561 ms 13.083 ms 13.646 ms] | 146 | | BlazeFace 320 (cpu) | [2.7741 ms 2.7817 ms 2.7900 ms] | 147 | | BlazeFace 640 (cpu) | [3.3369 ms 3.3430 ms 3.3498 ms] | 148 | 149 | *GPU times are ommited because the architectures are too small, causing them to be similar to CPU. 150 | 151 | ## Contributions 152 | 153 | Contributions to the project are welcome! If you have suggestions, bug reports, or would like to add support for additional face detection models or programming languages, please feel free to submit a pull request or open an issue. 154 | 155 | Backlog: https://github.com/users/rustybuilder/projects/1 156 | 157 | ## License 158 | 159 | This project is licensed under the MIT License. 160 | -------------------------------------------------------------------------------- /src/builder.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use ort::{ 4 | execution_providers::{CUDAExecutionProviderOptions, CoreMLExecutionProviderOptions}, 5 | ExecutionProvider, 6 | }; 7 | 8 | use crate::{ 9 | blazeface::BlazeFaceParams, 10 | detection::{FaceDetector, RustFacesResult}, 11 | model_repository::{GitHubRepository, ModelRepository}, 12 | BlazeFace, MtCnn, MtCnnParams, 13 | }; 14 | 15 | pub enum FaceDetection { 16 | BlazeFace640(BlazeFaceParams), 17 | BlazeFace320(BlazeFaceParams), 18 | MtCnn(MtCnnParams), 19 | } 20 | 21 | #[derive(Clone, Debug)] 22 | enum OpenMode { 23 | File(String), 24 | Download, 25 | } 26 | 27 | /// Runtime inference provider. Some may not be available depending of your Onnx runtime installation. 28 | #[derive(Clone, Copy, Debug)] 29 | pub enum Provider { 30 | /// Uses the, default, CPU inference 31 | OrtCpu, 32 | /// Uses the Cuda inference. 33 | OrtCuda(i32), 34 | /// Uses Intel's OpenVINO inference. 35 | OrtVino(i32), 36 | /// Apple's Core ML inference. 37 | OrtCoreMl, 38 | } 39 | 40 | /// Inference parameters. 41 | pub struct InferParams { 42 | /// Chooses the ONNX runtime provider. 43 | pub provider: Provider, 44 | /// Sets the number of intra-op threads. 45 | pub intra_threads: Option, 46 | /// Sets the number of inter-op threads. 47 | pub inter_threads: Option, 48 | } 49 | 50 | impl Default for InferParams { 51 | /// Default provider is `OrtCpu` (Onnx CPU). 52 | fn default() -> Self { 53 | Self { 54 | provider: Provider::OrtCpu, 55 | intra_threads: None, 56 | inter_threads: None, 57 | } 58 | } 59 | } 60 | 61 | /// Builder for loading or downloading, configuring, and creating face detectors. 62 | pub struct FaceDetectorBuilder { 63 | detector: FaceDetection, 64 | open_mode: OpenMode, 65 | infer_params: InferParams, 66 | } 67 | 68 | impl FaceDetectorBuilder { 69 | /// Create a new builder for the given face detector. 70 | /// 71 | /// # Arguments 72 | /// 73 | /// * `detector` - The face detector to build. 74 | pub fn new(detector: FaceDetection) -> Self { 75 | Self { 76 | detector, 77 | open_mode: OpenMode::Download, 78 | infer_params: InferParams::default(), 79 | } 80 | } 81 | 82 | /// Load the model from the given file path. 83 | /// 84 | /// # Arguments 85 | /// 86 | /// * `path` - Path to the model file. 87 | pub fn from_file(mut self, path: String) -> Self { 88 | self.open_mode = OpenMode::File(path); 89 | self 90 | } 91 | 92 | /// Sets the model to be downloaded from the model repository. 93 | pub fn download(mut self) -> Self { 94 | self.open_mode = OpenMode::Download; 95 | self 96 | } 97 | 98 | /// Sets the inference parameters. 99 | pub fn infer_params(mut self, params: InferParams) -> Self { 100 | self.infer_params = params; 101 | self 102 | } 103 | 104 | /// Instantiates a new detector. 105 | /// 106 | /// # Errors 107 | /// 108 | /// Returns an error if the model can't be loaded. 109 | /// 110 | /// # Returns 111 | /// 112 | /// A new face detector. 113 | pub fn build(&self) -> RustFacesResult> { 114 | let mut ort_builder = ort::Environment::builder().with_name("RustFaces"); 115 | 116 | ort_builder = match self.infer_params.provider { 117 | Provider::OrtCuda(device_id) => { 118 | let provider = ExecutionProvider::CUDA(CUDAExecutionProviderOptions { 119 | device_id: device_id as u32, 120 | ..Default::default() 121 | }); 122 | 123 | if !provider.is_available() { 124 | eprintln!("Warning: CUDA is not available. It'll likely use CPU inference."); 125 | } 126 | ort_builder.with_execution_providers([provider]) 127 | } 128 | Provider::OrtVino(_device_id) => { 129 | return Err(crate::RustFacesError::Other( 130 | "OpenVINO is not supported yet.".to_string(), 131 | )); 132 | } 133 | Provider::OrtCoreMl => { 134 | ort_builder.with_execution_providers([ExecutionProvider::CoreML( 135 | CoreMLExecutionProviderOptions::default(), 136 | )]) 137 | } 138 | _ => ort_builder, 139 | }; 140 | 141 | let env = Arc::new(ort_builder.build()?); 142 | let repository = GitHubRepository::new(); 143 | 144 | let model_paths = match &self.open_mode { 145 | OpenMode::Download => repository 146 | .get_model(&self.detector)? 147 | .iter() 148 | .map(|path| path.to_str().unwrap().to_string()) 149 | .collect(), 150 | OpenMode::File(path) => vec![path.clone()], 151 | }; 152 | 153 | match &self.detector { 154 | FaceDetection::BlazeFace640(params) => Ok(Box::new(BlazeFace::from_file( 155 | env, 156 | &model_paths[0], 157 | params.clone(), 158 | ))), 159 | FaceDetection::BlazeFace320(params) => Ok(Box::new(BlazeFace::from_file( 160 | env, 161 | &model_paths[0], 162 | params.clone(), 163 | ))), 164 | FaceDetection::MtCnn(params) => Ok(Box::new( 165 | MtCnn::from_file( 166 | env, 167 | &model_paths[0], 168 | &model_paths[1], 169 | &model_paths[2], 170 | params.clone(), 171 | ) 172 | .unwrap(), 173 | )), 174 | } 175 | } 176 | } 177 | 178 | #[cfg(test)] 179 | mod tests {} 180 | -------------------------------------------------------------------------------- /src/rect.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | /// Rectangle. 4 | #[derive(Debug, Clone, Copy)] 5 | pub struct Rect { 6 | /// X coordinate of the top-left corner. 7 | pub x: f32, 8 | /// Y coordinate of the top-left corner. 9 | pub y: f32, 10 | /// Width of the rectangle. 11 | pub width: f32, 12 | /// Height of the rectangle. 13 | pub height: f32, 14 | } 15 | 16 | /// Rectangle position used for chaining constructors. 17 | pub struct RectPosition { 18 | pub x: f32, 19 | pub y: f32, 20 | } 21 | 22 | impl RectPosition { 23 | /// Makes a rectangle with the given size. 24 | pub fn with_size(&self, width: f32, height: f32) -> Rect { 25 | Rect { 26 | x: self.x, 27 | y: self.y, 28 | width, 29 | height, 30 | } 31 | } 32 | 33 | /// Makes a rectangle with the given end point. 34 | pub fn ending_at(&self, x: f32, y: f32) -> Rect { 35 | Rect { 36 | x: self.x, 37 | y: self.y, 38 | width: x - self.x, 39 | height: y - self.y, 40 | } 41 | } 42 | } 43 | 44 | impl Rect { 45 | /// Starts a rectangle with the given position. 46 | pub fn at(x: f32, y: f32) -> RectPosition { 47 | RectPosition { x, y } 48 | } 49 | 50 | /// Right end of the rectangle. 51 | pub fn right(&self) -> f32 { 52 | self.x + self.width 53 | } 54 | 55 | /// Bottom end of the rectangle. 56 | pub fn bottom(&self) -> f32 { 57 | self.y + self.height 58 | } 59 | 60 | /// Unites two rectangles. 61 | /// 62 | /// # Arguments 63 | /// 64 | /// * `other` - Other rectangle to unite with. 65 | /// 66 | /// # Returns 67 | /// 68 | /// * `Rect` - United rectangle. 69 | pub fn union(&self, other: &Rect) -> Rect { 70 | let left = self.x.min(other.x); 71 | let right = self.right().max(other.right()); 72 | let top = self.y.min(other.y); 73 | let bottom = self.bottom().max(other.bottom()); 74 | 75 | Rect { 76 | x: left, 77 | y: top, 78 | width: right - left, 79 | height: bottom - top, 80 | } 81 | } 82 | 83 | /// Intersects two rectangles. 84 | /// 85 | /// # Arguments 86 | /// 87 | /// * `other` - Other rectangle to intersect with. 88 | /// 89 | /// # Returns 90 | /// 91 | /// * `Rect` - Intersected rectangle. 92 | pub fn intersection(&self, other: &Rect) -> Rect { 93 | let left = self.x.max(other.x); 94 | let right = self.right().min(other.right()); 95 | let top = self.y.max(other.y); 96 | let bottom = self.bottom().min(other.bottom()); 97 | 98 | Rect { 99 | x: left, 100 | y: top, 101 | width: right - left, 102 | height: bottom - top, 103 | } 104 | } 105 | 106 | /// Clamps the rectangle to the given rect. 107 | /// If the rectangle is larger than the given size, it will be shrunk. 108 | /// 109 | /// # Arguments 110 | /// 111 | /// * `width` - Width to clamp to. 112 | /// * `height` - Height to clamp to. 113 | pub fn clamp(&self, width: f32, height: f32) -> Rect { 114 | let left = self.x.max(0.0); 115 | let right = self.right().min(width); 116 | let top = self.y.max(0.0); 117 | let bottom = self.bottom().min(height); 118 | 119 | Rect { 120 | x: left, 121 | y: top, 122 | width: right - left, 123 | height: bottom - top, 124 | } 125 | } 126 | 127 | /// Calculates the intersection over union of two rectangles. 128 | /// 129 | /// # Arguments 130 | /// 131 | /// * `other` - Other rectangle to calculate the intersection over union with. 132 | /// 133 | /// # Returns 134 | /// 135 | /// * `f32` - Intersection over union. 136 | pub fn iou(&self, other: &Rect) -> f32 { 137 | let left = self.x.max(other.x); 138 | let right = (self.right()).min(other.right()); 139 | let top = self.y.max(other.y); 140 | let bottom = (self.bottom()).min(other.bottom()); 141 | 142 | let intersection = (right - left).max(0.0) * (bottom - top).max(0.0); 143 | let area_self = self.width * self.height; 144 | let area_other = other.width * other.height; 145 | 146 | intersection / (area_self + area_other - intersection) 147 | } 148 | 149 | /// Calculates the intersection over union of two rectangles. 150 | /// 151 | /// # Arguments 152 | /// 153 | /// * `other` - Other rectangle to calculate the intersection over union with. 154 | /// 155 | /// # Returns 156 | /// 157 | /// * `f32` - Intersection over union. 158 | pub fn iou_min(&self, other: &Rect) -> f32 { 159 | let left = self.x.max(other.x); 160 | let right = (self.right()).min(other.right()); 161 | let top = self.y.max(other.y); 162 | let bottom = (self.bottom()).min(other.bottom()); 163 | 164 | let intersection = (right - left).max(0.0) * (bottom - top).max(0.0); 165 | let area_self = self.width * self.height; 166 | let area_other = other.width * other.height; 167 | 168 | intersection / area_self.min(area_other) 169 | } 170 | 171 | /// Scales the rectangle. 172 | pub fn scale(&self, x_scale: f32, y_scale: f32) -> Rect { 173 | Rect { 174 | x: self.x * x_scale, 175 | y: self.y * y_scale, 176 | width: self.width * x_scale, 177 | height: self.height * y_scale, 178 | } 179 | } 180 | 181 | /// Gets the rectangle as a tuple of (x, y, width, height). 182 | pub fn to_xywh(&self) -> (f32, f32, f32, f32) { 183 | (self.x, self.y, self.width, self.height) 184 | } 185 | } 186 | 187 | impl Display for Rect { 188 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 189 | write!( 190 | f, 191 | "{{x: {}, y: {}, width: {}, height: {}}}", 192 | self.x, self.y, self.width, self.height 193 | ) 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /python/src/lib.rs: -------------------------------------------------------------------------------- 1 | use numpy::{ 2 | ndarray::{Array1, Array2, Array3}, 3 | IntoPyArray, PyArray1, PyArray2, PyArray3, PyReadonlyArrayDyn, 4 | }; 5 | use pyo3::prelude::*; 6 | use rust::Nms; 7 | use rust_faces as rust; 8 | 9 | #[pyclass] 10 | #[derive(Copy, Clone)] 11 | enum BlazeFace { 12 | Net640 = 0, 13 | Net320 = 1, 14 | } 15 | 16 | #[pyclass] 17 | #[derive(Copy, Clone)] 18 | #[allow(clippy::enum_variant_names)] 19 | enum InferProvider { 20 | OrtCpu = 0, 21 | OrtCuda = 1, 22 | OrtVino = 2, 23 | OrtCoreMl = 3, 24 | } 25 | 26 | /// Face detector wrapper. 27 | #[pyclass] 28 | struct FaceDetector { 29 | detector: Box, 30 | } 31 | 32 | #[pymethods] 33 | impl FaceDetector { 34 | /// Detects faces in an image. 35 | /// 36 | /// # Arguments 37 | /// 38 | /// * `image` - The image to detect faces in. Must be a 3D array of shape (height, width, channels) with type uint8. 39 | /// 40 | /// # Returns 41 | /// 42 | /// A tuple containing: 43 | /// 44 | /// * `rects` - A 2D array of shape (num_faces, 4) containing the bounding boxes of the detected faces. 45 | /// * `scores` - A 1D array of shape (num_faces,) containing the confidence scores of the detected faces. 46 | /// * `landmarks` - A 3D array of shape (num_faces, num_landmarks, 2) containing the landmarks of the detected faces. 47 | fn detect<'py>( 48 | &self, 49 | py: Python<'py>, 50 | image: PyReadonlyArrayDyn, 51 | ) -> (&'py PyArray2, &'py PyArray1, &'py PyArray3) { 52 | let array = image.as_array(); 53 | let faces = self.detector.detect(array.view()).unwrap(); 54 | 55 | let (rect_array, score_array, landmarks_array) = { 56 | let mut rect_array = Array2::zeros((faces.len(), 4)); 57 | let mut score_array = Array1::zeros(faces.len()); 58 | let num_landmarks = faces 59 | .first() 60 | .map(|f| f.landmarks.as_ref().map(|lms| lms.len()).unwrap_or(0)) 61 | .unwrap_or(0); 62 | 63 | let mut landmarks_array = Array3::::zeros((faces.len(), num_landmarks, 2)); 64 | for i in 0..faces.len() { 65 | let face = &faces[i]; 66 | rect_array[(i, 0)] = face.rect.x; 67 | rect_array[(i, 1)] = face.rect.y; 68 | rect_array[(i, 2)] = face.rect.width; 69 | rect_array[(i, 3)] = face.rect.height; 70 | 71 | score_array[i] = face.confidence; 72 | 73 | if let Some(landmarks) = face.landmarks.as_ref() { 74 | for j in 0..num_landmarks { 75 | landmarks_array[(i, j, 0)] = landmarks[j].0; 76 | landmarks_array[(i, j, 1)] = landmarks[j].1; 77 | } 78 | } 79 | } 80 | (rect_array, score_array, landmarks_array) 81 | }; 82 | 83 | ( 84 | rect_array.into_pyarray(py), 85 | score_array.into_pyarray(py), 86 | landmarks_array.into_pyarray(py), 87 | ) 88 | } 89 | } 90 | 91 | fn build( 92 | detector: rust::FaceDetection, 93 | model_path: Option<&str>, 94 | infer_provider: Option, 95 | device_id: i32, 96 | ) -> PyResult { 97 | let mut builder = rust::FaceDetectorBuilder::new(detector); 98 | 99 | builder = if let Some(model_path) = model_path { 100 | builder.from_file(model_path.to_string()) 101 | } else { 102 | builder.download() 103 | }; 104 | 105 | let provider = match infer_provider { 106 | Some(InferProvider::OrtCpu) => rust::Provider::OrtCpu, 107 | Some(InferProvider::OrtCuda) => rust::Provider::OrtCuda(device_id), 108 | Some(InferProvider::OrtVino) => rust::Provider::OrtVino(device_id), 109 | Some(InferProvider::OrtCoreMl) => rust::Provider::OrtCoreMl, 110 | _ => rust::Provider::OrtCuda(0), 111 | }; 112 | 113 | let detector_impl = builder 114 | .infer_params(rust::InferParams { 115 | provider, 116 | ..Default::default() 117 | }) 118 | .build(); 119 | 120 | if let Err(err) = detector_impl { 121 | Err(PyErr::new::(format!( 122 | "Failed to build detector: {}", 123 | err 124 | ))) 125 | } else { 126 | Ok(FaceDetector { 127 | detector: detector_impl.unwrap(), 128 | }) 129 | } 130 | } 131 | 132 | /// Builds a MTCNN-based face detector. 133 | /// 134 | /// # Arguments 135 | /// 136 | /// * `model_path` - Path to directory containing the `pnet.onnx`, `rnet.onnx`, `onet.onnx`. 137 | /// If not specified, the model will be downloaded. 138 | /// * `score_thresholds` - A tuple of three floats representing the thresholds for the three stages of the MTCNN. 139 | /// * `nms_iou` - The IoU threshold for non-maximum suppression. 140 | /// * `infer_provider` - The inference provider to use. 141 | /// * `device_id` - The device ID to use. 142 | #[pyfunction] 143 | #[pyo3(signature = (model_path=None, score_thresholds=(0.6, 0.6, 0.95), 144 | nms_iou=0.3, 145 | min_face_size=24, 146 | scale_factor=0.709, 147 | infer_provider=None, device_id=0))] 148 | fn mtcnn( 149 | model_path: Option<&str>, 150 | score_thresholds: (f32, f32, f32), 151 | nms_iou: f32, 152 | min_face_size: usize, 153 | scale_factor: f32, 154 | infer_provider: Option, 155 | device_id: i32, 156 | ) -> PyResult { 157 | let detector = rust::FaceDetection::MtCnn(rust::MtCnnParams { 158 | min_face_size, 159 | scale_factor, 160 | thresholds: [score_thresholds.0, score_thresholds.1, score_thresholds.2], 161 | nms: Nms { 162 | iou_threshold: nms_iou, 163 | }, 164 | }); 165 | 166 | build(detector, model_path, infer_provider, device_id) 167 | } 168 | 169 | /// Builds a BlazeFace-based face detector. 170 | /// 171 | /// # Arguments 172 | /// 173 | /// * `blazeface_type` - The type of BlazeFace model to use. 174 | /// * `model_path` - Path to directory containing the `blazeface.onnx`. 175 | /// If not specified, the model will be downloaded. 176 | /// * `score_threshold` - The confidence threshold for face detection. 177 | /// * `nms_iou` - The IoU threshold for non-maximum suppression. 178 | /// * `infer_provider` - The inference provider to use. 179 | /// * `device_id` - The device ID to use. 180 | /// 181 | /// # Returns 182 | /// 183 | /// A `FaceDetector` instance. 184 | #[pyfunction] 185 | #[pyo3(signature = (blazeface_type, model_path=None, score_threshold=0.95, nms_iou=0.3, infer_provider=None, device_id=0))] 186 | fn blazeface( 187 | blazeface_type: BlazeFace, 188 | model_path: Option<&str>, 189 | score_threshold: f32, 190 | nms_iou: f32, 191 | infer_provider: Option, 192 | device_id: i32, 193 | ) -> PyResult { 194 | let params = rust::BlazeFaceParams { 195 | score_threshold, 196 | nms: Nms { 197 | iou_threshold: nms_iou, 198 | }, 199 | ..Default::default() 200 | }; 201 | 202 | let detection_method = match blazeface_type { 203 | BlazeFace::Net640 => rust::FaceDetection::BlazeFace640(params), 204 | BlazeFace::Net320 => rust::FaceDetection::BlazeFace320(params), 205 | }; 206 | 207 | build(detection_method, model_path, infer_provider, device_id) 208 | } 209 | 210 | /// py-rust-faces is a Python binding to the rust-faces library. 211 | /// (https://github.com/rustybuilder/rust-faces/) 212 | #[pymodule] 213 | fn py_rust_faces(_py: Python<'_>, m: &PyModule) -> PyResult<()> { 214 | m.add_class::()?; 215 | m.add_class::()?; 216 | m.add_class::()?; 217 | m.add_function(wrap_pyfunction!(blazeface, m)?)?; 218 | m.add_function(wrap_pyfunction!(mtcnn, m)?)?; 219 | Ok(()) 220 | } 221 | -------------------------------------------------------------------------------- /src/blazeface.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use image::{ 4 | imageops::{self, FilterType}, 5 | GenericImageView, ImageBuffer, Pixel, Rgb, 6 | }; 7 | use itertools::Itertools; 8 | use ndarray::{Array3, ArrayViewD, Axis, CowArray}; 9 | use ort::{tensor::OrtOwnedTensor, Value}; 10 | 11 | use crate::{ 12 | detection::{FaceDetector, RustFacesResult}, 13 | imaging::make_border, 14 | priorboxes::{PriorBoxes, PriorBoxesParams}, 15 | Face, Nms, 16 | }; 17 | 18 | pub type Image

= ImageBuffer::Subpixel>>; 19 | 20 | fn resize_and_border( 21 | image: &I, 22 | output_size: (u32, u32), 23 | border_color: I::Pixel, 24 | ) -> (Image, f32) 25 | where 26 | I::Pixel: 'static, 27 | ::Subpixel: 'static, 28 | { 29 | let (input_width, input_height) = image.dimensions(); 30 | let (output_width, output_height) = output_size; 31 | let ratio = (output_width as f32 / input_width as f32) 32 | .min(output_height as f32 / input_height as f32) 33 | .min(1.0); // avoid scaling up. 34 | 35 | let (resize_width, resize_height) = ( 36 | (input_width as f32 * ratio).round() as i32, 37 | (input_height as f32 * ratio).round() as i32, 38 | ); 39 | let resized = imageops::resize( 40 | image, 41 | resize_width as u32, 42 | resize_height as u32, 43 | FilterType::Nearest, 44 | ); 45 | 46 | let (left, right, top, bottom) = { 47 | let (x_pad, y_pad) = ( 48 | ((output_width as i32 - resize_width) % 16) as f32 / 2.0, 49 | ((output_height as i32 - resize_height) % 16) as f32 / 2.0, 50 | ); 51 | ( 52 | (x_pad - 0.1).round() as u32, 53 | (x_pad + 0.1).round() as u32, 54 | (y_pad - 0.1).round() as u32, 55 | (y_pad + 0.1).round() as u32, 56 | ) 57 | }; 58 | 59 | ( 60 | make_border(&resized, top, bottom, left, right, border_color), 61 | ratio, 62 | ) 63 | } 64 | 65 | #[derive(Debug, Clone)] 66 | pub struct BlazeFaceParams { 67 | pub score_threshold: f32, 68 | pub nms: Nms, 69 | pub target_size: usize, 70 | pub prior_boxes: PriorBoxesParams, 71 | } 72 | 73 | impl Default for BlazeFaceParams { 74 | fn default() -> Self { 75 | Self { 76 | score_threshold: 0.95, 77 | nms: Nms::default(), 78 | target_size: 1280, 79 | prior_boxes: PriorBoxesParams::default(), 80 | } 81 | } 82 | } 83 | 84 | pub struct BlazeFace { 85 | session: ort::Session, 86 | params: BlazeFaceParams, 87 | } 88 | 89 | impl BlazeFace { 90 | pub fn from_file( 91 | env: Arc, 92 | model_path: &str, 93 | params: BlazeFaceParams, 94 | ) -> Self { 95 | let session = ort::session::SessionBuilder::new(&env) 96 | .unwrap() 97 | .with_model_from_file(model_path) 98 | .unwrap(); 99 | Self { session, params } 100 | } 101 | } 102 | 103 | impl FaceDetector for BlazeFace { 104 | fn detect(&self, image: ArrayViewD) -> RustFacesResult> { 105 | let shape = image.shape().to_vec(); 106 | let (width, height, _) = (shape[1], shape[0], shape[2]); 107 | 108 | let image = ImageBuffer::, &[u8]>::from_raw( 109 | width as u32, 110 | height as u32, 111 | image.as_slice().unwrap(), 112 | ) 113 | .unwrap(); 114 | 115 | let (image, ratio) = resize_and_border( 116 | &image, 117 | ( 118 | self.params.target_size as u32, 119 | self.params.target_size as u32, 120 | ), 121 | Rgb([104, 117, 123]), 122 | ); 123 | let (input_width, input_height) = image.dimensions(); 124 | let image = Array3::::from_shape_fn( 125 | (3, input_height as usize, input_width as usize), 126 | |(c, y, x)| { 127 | match c { 128 | // https://github.com/zineos/blazeface/blob/main/tools/test.py seems to use OpenCV's BGR 129 | 0 => image.get_pixel(x as u32, y as u32)[2] as f32 - 104.0, 130 | 1 => image.get_pixel(x as u32, y as u32)[1] as f32 - 117.0, 131 | 2 => image.get_pixel(x as u32, y as u32)[0] as f32 - 123.0, 132 | _ => unreachable!(), 133 | } 134 | }, 135 | ) 136 | .insert_axis(Axis(0)); 137 | 138 | let output_tensors = self.session.run(vec![Value::from_array( 139 | self.session.allocator(), 140 | &CowArray::from(image).into_dyn(), 141 | )?])?; 142 | 143 | // Boxes regressions: N box with the format [start x, start y, end x, end y]. 144 | let boxes: OrtOwnedTensor = output_tensors[0].try_extract()?; 145 | let scores: OrtOwnedTensor = output_tensors[1].try_extract()?; 146 | let landmarks: OrtOwnedTensor = output_tensors[2].try_extract()?; 147 | let num_boxes = boxes.view().shape()[1]; 148 | 149 | let priors = PriorBoxes::new( 150 | &self.params.prior_boxes, 151 | (input_width as usize, input_height as usize), 152 | ); 153 | 154 | let scale_ratios = (input_width as f32 / ratio, input_height as f32 / ratio); 155 | 156 | let faces = boxes 157 | .view() 158 | .to_shape((num_boxes, 4)) 159 | .unwrap() 160 | .axis_iter(Axis(0)) 161 | .zip( 162 | landmarks 163 | .view() 164 | .to_shape((num_boxes, 10)) 165 | .unwrap() 166 | .axis_iter(Axis(0)), 167 | ) 168 | .zip(priors.anchors.iter()) 169 | .zip( 170 | scores 171 | .view() 172 | .to_shape((num_boxes, 2)) 173 | .unwrap() 174 | .axis_iter(Axis(0)), 175 | ) 176 | .filter_map(|(((rect, landmarks), prior), score)| { 177 | let score = score[1]; 178 | 179 | if score > self.params.score_threshold { 180 | let rect = priors.decode_box(prior, &(rect[0], rect[1], rect[2], rect[3])); 181 | let rect = rect.scale(scale_ratios.0, scale_ratios.1); 182 | 183 | let landmarks = landmarks 184 | .to_vec() 185 | .chunks(2) 186 | .map(|point| { 187 | let point = priors.decode_landmark(prior, (point[0], point[1])); 188 | (point.0 * scale_ratios.0, point.1 * scale_ratios.1) 189 | }) 190 | .collect::>(); 191 | 192 | Some(Face { 193 | rect, 194 | landmarks: Some(landmarks), 195 | confidence: score, 196 | }) 197 | } else { 198 | None 199 | } 200 | }) 201 | .collect_vec(); 202 | 203 | Ok(self.params.nms.suppress_non_maxima(faces)) 204 | } 205 | } 206 | 207 | #[cfg(test)] 208 | mod tests { 209 | use crate::{ 210 | imaging::ToRgb8, 211 | model_repository::{GitHubRepository, ModelRepository}, 212 | testing::{output_dir, sample_array_image, sample_image}, 213 | }; 214 | 215 | use super::*; 216 | use image::RgbImage; 217 | use rstest::rstest; 218 | 219 | use std::path::PathBuf; 220 | 221 | #[rstest] 222 | pub fn test_resize_and_border(sample_image: RgbImage, output_dir: PathBuf) { 223 | let (resized, _) = resize_and_border(&sample_image, (1280, 1280), Rgb([0, 255, 0])); 224 | 225 | resized.save(output_dir.join("test_resized.jpg")).unwrap(); 226 | assert!(resized.width() == 896); 227 | assert!(resized.height() == 1280); 228 | } 229 | 230 | #[cfg(feature = "viz")] 231 | fn should_detect_impl( 232 | blaze_model: crate::FaceDetection, 233 | sample_array_image: Array3, 234 | output_dir: PathBuf, 235 | ) { 236 | use crate::viz; 237 | let environment = Arc::new( 238 | ort::Environment::builder() 239 | .with_name("BlazeFace") 240 | .build() 241 | .unwrap(), 242 | ); 243 | 244 | let params = match &blaze_model { 245 | crate::FaceDetection::BlazeFace640(params) => params.clone(), 246 | crate::FaceDetection::BlazeFace320(params) => params.clone(), 247 | _ => unreachable!(), 248 | }; 249 | 250 | let drive = GitHubRepository::new(); 251 | let model_path = drive.get_model(&blaze_model).expect("Can't download model")[0].clone(); 252 | 253 | let face_detector = BlazeFace::from_file(environment, model_path.to_str().unwrap(), params); 254 | let mut canvas = sample_array_image.to_rgb8(); 255 | let faces = face_detector 256 | .detect(sample_array_image.into_dyn().view()) 257 | .unwrap(); 258 | 259 | viz::draw_faces(&mut canvas, faces); 260 | 261 | canvas 262 | .save(output_dir.join("blazefaces.png")) 263 | .expect("Can't save image"); 264 | } 265 | 266 | #[rstest] 267 | #[cfg(feature = "viz")] 268 | fn should_detect_640(sample_array_image: Array3, output_dir: PathBuf) { 269 | should_detect_impl( 270 | crate::FaceDetection::BlazeFace640(BlazeFaceParams::default()), 271 | sample_array_image, 272 | output_dir, 273 | ); 274 | } 275 | 276 | #[rstest] 277 | #[cfg(feature = "viz")] 278 | fn should_detect_320(sample_array_image: Array3, output_dir: PathBuf) { 279 | should_detect_impl( 280 | crate::FaceDetection::BlazeFace320(BlazeFaceParams::default()), 281 | sample_array_image, 282 | output_dir, 283 | ); 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /src/mtcnn.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use image::{ 4 | imageops::{self, FilterType}, 5 | ImageBuffer, Rgb, RgbImage, 6 | }; 7 | use ndarray::{s, Array3, Array4, ArrayViewD, Axis, CowArray, Zip}; 8 | use ort::tensor::OrtOwnedTensor; 9 | 10 | use crate::{Face, FaceDetector, Nms, Rect, RustFacesResult}; 11 | 12 | /// MtCnn parameters. 13 | #[derive(Clone)] 14 | pub struct MtCnnParams { 15 | /// Minimum face size in pixels. 16 | pub min_face_size: usize, 17 | /// Confidence thresholds for each stage. 18 | pub thresholds: [f32; 3], 19 | /// Scale factor for the next pyramid image. 20 | pub scale_factor: f32, 21 | /// Non-maximum suppression. 22 | pub nms: Nms, 23 | } 24 | 25 | impl Default for MtCnnParams { 26 | fn default() -> Self { 27 | Self { 28 | min_face_size: 24, 29 | thresholds: [0.6, 0.7, 0.7], 30 | scale_factor: 0.709, 31 | nms: Nms::default(), 32 | } 33 | } 34 | } 35 | 36 | /// MtCnn face detector. 37 | pub struct MtCnn { 38 | pnet: ort::Session, 39 | rnet: ort::Session, 40 | onet: ort::Session, 41 | params: MtCnnParams, 42 | } 43 | 44 | impl MtCnn { 45 | /// Creates a new MtCnn face detector from the given ONNX model paths. 46 | /// 47 | /// # Arguments 48 | /// 49 | /// * `pnet_path` - Path to the P(roposal)Net ONNX model. 50 | /// * `rnet_path` - Path to the R(efine)Net ONNX model. 51 | /// * `onet_path` - Path to the O(ptimize)Net ONNX model. 52 | /// * `params` - MtCnn parameters. 53 | /// 54 | /// # Returns 55 | /// 56 | /// * `MtCnn` - MtCnn face detector. 57 | pub fn from_file( 58 | env: Arc, 59 | pnet_path: &str, 60 | rnet_path: &str, 61 | onet_path: &str, 62 | params: MtCnnParams, 63 | ) -> RustFacesResult { 64 | let pnet = ort::session::SessionBuilder::new(&env)?.with_model_from_file(pnet_path)?; 65 | let rnet = ort::session::SessionBuilder::new(&env)?.with_model_from_file(rnet_path)?; 66 | let onet = ort::session::SessionBuilder::new(&env)?.with_model_from_file(onet_path)?; 67 | 68 | Ok(Self { 69 | pnet, 70 | rnet, 71 | onet, 72 | params, 73 | }) 74 | } 75 | 76 | fn run_proposal_inference( 77 | &self, 78 | image: &ImageBuffer, &[u8]>, 79 | ) -> Result, crate::RustFacesError> { 80 | const PNET_CELL_SIZE: usize = 12; 81 | const PNET_STRIDE: usize = 2; 82 | 83 | let (image_width, image_height) = (image.width() as usize, image.height() as usize); 84 | 85 | let scales = { 86 | // Make the first scale to match the minimum face size. 87 | // Example, if the minimum face size is the same as PNET_CELL_SIZE, 88 | // that means each cell in the output feature map will correspond 89 | // to a 12x12 pixel region in the input image, hence no resize (first_scale = 1.0). 90 | let first_scale = PNET_CELL_SIZE as f32 / self.params.min_face_size as f32; 91 | 92 | let mut curr_size = image_width.min(image_height) as f32 * first_scale; 93 | let mut scale = first_scale; 94 | let mut scales = Vec::new(); 95 | 96 | while curr_size > PNET_CELL_SIZE as f32 { 97 | scales.push(scale); 98 | scale *= self.params.scale_factor; 99 | curr_size *= self.params.scale_factor; 100 | } 101 | scales 102 | }; 103 | 104 | let mut face_proposals = Vec::new(); 105 | for scale_factor in scales { 106 | let image = imageops::resize( 107 | image, 108 | (scale_factor * image_width as f32) as u32, 109 | (scale_factor * image_height as f32) as u32, 110 | FilterType::Gaussian, 111 | ); 112 | 113 | let (in_width, in_height) = image.dimensions(); 114 | let image = Array4::from_shape_fn( 115 | (1, 3, in_height as usize, in_width as usize), 116 | |(_n, c, h, w)| (image.get_pixel(w as u32, h as u32)[c] as f32 - 127.5) / 128.0, 117 | ); 118 | 119 | let output_tensors = self.pnet.run(vec![ort::Value::from_array( 120 | self.pnet.allocator(), 121 | &CowArray::from(image).into_dyn(), 122 | )?])?; 123 | 124 | let box_regressions: OrtOwnedTensor = output_tensors[0].try_extract()?; 125 | let scores: OrtOwnedTensor = output_tensors[1].try_extract()?; 126 | 127 | let (net_out_width, net_out_height) = { 128 | let shape = scores.view().dim(); 129 | (shape[3], shape[2]) 130 | }; 131 | 132 | let rescale_factor = 1.0 / scale_factor; 133 | let mut faces = Vec::with_capacity(net_out_width * net_out_height); 134 | 135 | Zip::indexed( 136 | scores 137 | .view() 138 | .to_shape((2, net_out_height, net_out_width)) 139 | .unwrap() 140 | .lanes(Axis(0)), 141 | ) 142 | .and( 143 | box_regressions 144 | .view() 145 | .to_shape((4, net_out_height, net_out_width)) 146 | .unwrap() 147 | .lanes(Axis(0)), 148 | ) 149 | .for_each(|(row, col), score, regression| { 150 | let score = score[1]; 151 | if score > self.params.thresholds[0] { 152 | let x1 = col as f32 * PNET_STRIDE as f32 + regression[0]; 153 | let y1 = row as f32 * PNET_STRIDE as f32 + regression[1]; 154 | let x2 = 155 | col as f32 * PNET_STRIDE as f32 + PNET_CELL_SIZE as f32 + regression[2]; 156 | let y2 = 157 | row as f32 * PNET_STRIDE as f32 + PNET_CELL_SIZE as f32 + regression[3]; 158 | 159 | faces.push(Face { 160 | rect: Rect::at(x1, y1) 161 | .ending_at(x2, y2) 162 | .scale(rescale_factor, rescale_factor), 163 | confidence: score, 164 | landmarks: None, 165 | }) 166 | } 167 | }); 168 | 169 | face_proposals.extend(self.params.nms.suppress_non_maxima(faces)); 170 | } 171 | let mut proposals = self.params.nms.suppress_non_maxima(face_proposals); 172 | proposals.iter_mut().for_each(|face| { 173 | face.rect = face.rect.clamp(image_width as f32, image_height as f32); 174 | }); 175 | Ok(proposals) 176 | } 177 | 178 | fn batch_faces<'a>( 179 | &self, 180 | image: &'a ImageBuffer, &[u8]>, 181 | proposals: &'a [Face], 182 | input_size: usize, 183 | ) -> impl Iterator)> + 'a { 184 | const BATCH_SIZE: usize = 16; 185 | proposals.chunks(BATCH_SIZE).map(move |proposal_batch| { 186 | let mut input_tensor = Array4::zeros((proposal_batch.len(), 3, input_size, input_size)); 187 | for (n, face) in proposal_batch.iter().enumerate() { 188 | let face_image = 189 | RgbImage::from_fn(face.rect.width as u32, face.rect.height as u32, |x, y| { 190 | image 191 | .get_pixel(face.rect.x as u32 + x, face.rect.y as u32 + y) 192 | .to_owned() 193 | }); 194 | let face_image = imageops::resize( 195 | &face_image, 196 | input_size as u32, 197 | input_size as u32, 198 | FilterType::Gaussian, 199 | ); 200 | input_tensor 201 | .slice_mut(s![n, .., .., ..]) 202 | .assign(&Array3::from_shape_fn( 203 | (3, input_size, input_size), 204 | |(c, h, w)| { 205 | (face_image.get_pixel(w as u32, h as u32)[c] as f32 - 127.5) / 128.0 206 | }, 207 | )); 208 | } 209 | (proposal_batch, input_tensor) 210 | }) 211 | } 212 | 213 | fn run_refine_net( 214 | &self, 215 | image: &ImageBuffer, &[u8]>, 216 | proposals: &[Face], 217 | ) -> Result, crate::RustFacesError> { 218 | let mut rnet_faces = Vec::new(); 219 | for (faces, input_tensor) in self.batch_faces(image, proposals, 24) { 220 | let output_tensors = self.rnet.run(vec![ort::Value::from_array( 221 | self.rnet.allocator(), 222 | &CowArray::from(input_tensor).into_dyn(), 223 | )?])?; 224 | let box_regressions: OrtOwnedTensor = output_tensors[0].try_extract()?; 225 | let scores: OrtOwnedTensor = output_tensors[1].try_extract()?; 226 | let image_width = (image.width() - 1) as f32; 227 | let image_height = (image.height() - 1) as f32; 228 | 229 | let batch_faces = itertools::izip!( 230 | faces.iter(), 231 | scores 232 | .view() 233 | .to_shape((faces.len(), 2)) 234 | .unwrap() 235 | .lanes(Axis(1)) 236 | .into_iter(), 237 | box_regressions 238 | .view() 239 | .to_shape((faces.len(), 4)) 240 | .unwrap() 241 | .lanes(Axis(1)) 242 | .into_iter() 243 | ) 244 | .filter_map(|(face, score, regression)| { 245 | let score = score[1]; 246 | if score >= self.params.thresholds[1] { 247 | let face_width = face.rect.width; 248 | let face_height = face.rect.height; 249 | let regression = regression.to_vec(); 250 | 251 | let x1 = face.rect.x + regression[0] * face_width; 252 | let y1 = face.rect.y + regression[1] * face_height; 253 | let x2 = face.rect.right() + regression[2] * face_width; 254 | let y2 = face.rect.bottom() + regression[3] * face_height; 255 | 256 | Some(Face { 257 | rect: Rect::at(x1, y1) 258 | .ending_at(x2, y2) 259 | .clamp(image_width, image_height), 260 | confidence: score, 261 | landmarks: None, 262 | }) 263 | } else { 264 | None 265 | } 266 | }) 267 | .collect::>(); 268 | 269 | rnet_faces.extend(batch_faces); 270 | } 271 | let boxes = self.params.nms.suppress_non_maxima_min(rnet_faces); 272 | Ok(boxes) 273 | } 274 | 275 | fn run_optmized_net( 276 | &self, 277 | image: &ImageBuffer, &[u8]>, 278 | proposals: &[Face], 279 | ) -> Result, crate::RustFacesError> { 280 | let mut onet_faces = Vec::new(); 281 | for (faces, input_tensor) in self.batch_faces(image, proposals, 48) { 282 | let output_tensors = self.onet.run(vec![ort::Value::from_array( 283 | self.onet.allocator(), 284 | &CowArray::from(input_tensor).into_dyn(), 285 | )?])?; 286 | 287 | let box_regressions: OrtOwnedTensor = output_tensors[0].try_extract()?; // 0 288 | let landmarks_regressions: OrtOwnedTensor = output_tensors[1].try_extract()?; 289 | let scores: OrtOwnedTensor = output_tensors[2].try_extract()?; // 1 290 | let image_width = (image.width() - 1) as f32; 291 | let image_height = (image.height() - 1) as f32; 292 | 293 | let batch_faces = itertools::izip!( 294 | faces.iter(), 295 | scores 296 | .view() 297 | .to_shape((faces.len(), 2)) 298 | .unwrap() 299 | .lanes(Axis(1)) 300 | .into_iter(), 301 | box_regressions 302 | .view() 303 | .to_shape((faces.len(), 4)) 304 | .unwrap() 305 | .lanes(Axis(1)) 306 | .into_iter(), 307 | landmarks_regressions 308 | .view() 309 | .to_shape((faces.len(), 10)) 310 | .unwrap() 311 | .lanes(Axis(1)) 312 | .into_iter() 313 | ) 314 | .filter_map(|(face, score, regression, landmarks)| { 315 | let score = score[1]; 316 | if score >= self.params.thresholds[1] { 317 | let face_width = face.rect.width; 318 | let face_height = face.rect.height; 319 | let regression = regression.to_vec(); 320 | 321 | let x1 = face.rect.x + regression[0] * face_width; 322 | let y1 = face.rect.y + regression[1] * face_height; 323 | let x2 = face.rect.right() + regression[2] * face_width; 324 | let y2 = face.rect.bottom() + regression[3] * face_height; 325 | 326 | let rect = Rect::at(x1, y1) 327 | .ending_at(x2, y2) 328 | .clamp(image_width, image_height); 329 | let mut landmarks_vec = Vec::new(); 330 | 331 | for i in 0..5 { 332 | landmarks_vec.push(( 333 | face.rect.x + landmarks[i] * face_width, 334 | face.rect.y + landmarks[i + 5] * face_height, 335 | )); 336 | } 337 | Some(Face { 338 | rect, 339 | confidence: score, 340 | landmarks: Some(landmarks_vec), 341 | }) 342 | } else { 343 | None 344 | } 345 | }) 346 | .collect::>(); 347 | 348 | onet_faces.extend(batch_faces); 349 | } 350 | let boxes = self.params.nms.suppress_non_maxima_min(onet_faces); 351 | Ok(boxes) 352 | } 353 | } 354 | 355 | impl FaceDetector for MtCnn { 356 | fn detect(&self, image: ArrayViewD) -> RustFacesResult> { 357 | let shape = image.shape().to_vec(); 358 | let (image_width, image_height) = (shape[1], shape[0]); 359 | let image = ImageBuffer::, &[u8]>::from_raw( 360 | image_width as u32, 361 | image_height as u32, 362 | image.as_slice().unwrap(), 363 | ) 364 | .unwrap(); 365 | 366 | let proposals = self.run_proposal_inference(&image)?; 367 | let refined_faces = self.run_refine_net(&image, &proposals)?; 368 | let optimized_faces = self.run_optmized_net(&image, &refined_faces)?; 369 | Ok(optimized_faces) 370 | } 371 | } 372 | 373 | #[cfg(test)] 374 | mod tests { 375 | use std::path::PathBuf; 376 | 377 | use super::*; 378 | use crate::{ 379 | imaging::ToRgb8, 380 | model_repository::{GitHubRepository, ModelRepository}, 381 | mtcnn::MtCnn, 382 | testing::{output_dir, sample_array_image}, 383 | viz, 384 | }; 385 | use ndarray::Array3; 386 | use rstest::rstest; 387 | use std::sync::Arc; 388 | 389 | #[cfg(feature = "viz")] 390 | #[rstest] 391 | fn should_detect(sample_array_image: Array3, output_dir: PathBuf) { 392 | use crate::FaceDetection; 393 | 394 | let environment = Arc::new( 395 | ort::Environment::builder() 396 | .with_name("MtCnn") 397 | .build() 398 | .unwrap(), 399 | ); 400 | 401 | let drive = GitHubRepository::new(); 402 | let model_paths = drive 403 | .get_model(&FaceDetection::MtCnn(MtCnnParams::default())) 404 | .expect("Can't download model"); 405 | 406 | let face_detector = MtCnn::from_file( 407 | environment, 408 | model_paths[0].to_str().unwrap(), 409 | model_paths[1].to_str().unwrap(), 410 | model_paths[2].to_str().unwrap(), 411 | MtCnnParams::default(), 412 | ) 413 | .expect("Failed to load MTCNN detector."); 414 | let mut canvas = sample_array_image.to_rgb8(); 415 | let faces = face_detector 416 | .detect(sample_array_image.into_dyn().view()) 417 | .expect("Can't detect faces"); 418 | 419 | viz::draw_faces(&mut canvas, faces); 420 | 421 | canvas 422 | .save(output_dir.join("mtcnn.png")) 423 | .expect("Can't save image"); 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /python/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "approx" 13 | version = "0.5.1" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" 16 | dependencies = [ 17 | "num-traits", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "base64" 28 | version = "0.21.2" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" 31 | 32 | [[package]] 33 | name = "bit_field" 34 | version = "0.10.2" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 37 | 38 | [[package]] 39 | name = "bitflags" 40 | version = "1.3.2" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 43 | 44 | [[package]] 45 | name = "bumpalo" 46 | version = "3.13.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 49 | 50 | [[package]] 51 | name = "bytemuck" 52 | version = "1.13.1" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" 55 | 56 | [[package]] 57 | name = "byteorder" 58 | version = "1.4.3" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 61 | 62 | [[package]] 63 | name = "bytes" 64 | version = "1.4.0" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 67 | 68 | [[package]] 69 | name = "cc" 70 | version = "1.0.79" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 73 | 74 | [[package]] 75 | name = "cfg-if" 76 | version = "1.0.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 79 | 80 | [[package]] 81 | name = "color_quant" 82 | version = "1.1.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 85 | 86 | [[package]] 87 | name = "console" 88 | version = "0.15.7" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" 91 | dependencies = [ 92 | "encode_unicode", 93 | "lazy_static", 94 | "libc", 95 | "unicode-width", 96 | "windows-sys 0.45.0", 97 | ] 98 | 99 | [[package]] 100 | name = "core-foundation" 101 | version = "0.9.3" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 104 | dependencies = [ 105 | "core-foundation-sys", 106 | "libc", 107 | ] 108 | 109 | [[package]] 110 | name = "core-foundation-sys" 111 | version = "0.8.4" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 114 | 115 | [[package]] 116 | name = "crc32fast" 117 | version = "1.3.2" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 120 | dependencies = [ 121 | "cfg-if", 122 | ] 123 | 124 | [[package]] 125 | name = "crossbeam-channel" 126 | version = "0.5.8" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" 129 | dependencies = [ 130 | "cfg-if", 131 | "crossbeam-utils", 132 | ] 133 | 134 | [[package]] 135 | name = "crossbeam-deque" 136 | version = "0.8.3" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" 139 | dependencies = [ 140 | "cfg-if", 141 | "crossbeam-epoch", 142 | "crossbeam-utils", 143 | ] 144 | 145 | [[package]] 146 | name = "crossbeam-epoch" 147 | version = "0.9.15" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" 150 | dependencies = [ 151 | "autocfg", 152 | "cfg-if", 153 | "crossbeam-utils", 154 | "memoffset", 155 | "scopeguard", 156 | ] 157 | 158 | [[package]] 159 | name = "crossbeam-utils" 160 | version = "0.8.16" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" 163 | dependencies = [ 164 | "cfg-if", 165 | ] 166 | 167 | [[package]] 168 | name = "crunchy" 169 | version = "0.2.2" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 172 | 173 | [[package]] 174 | name = "either" 175 | version = "1.8.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" 178 | 179 | [[package]] 180 | name = "encode_unicode" 181 | version = "0.3.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 184 | 185 | [[package]] 186 | name = "encoding_rs" 187 | version = "0.8.32" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" 190 | dependencies = [ 191 | "cfg-if", 192 | ] 193 | 194 | [[package]] 195 | name = "errno" 196 | version = "0.3.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" 199 | dependencies = [ 200 | "errno-dragonfly", 201 | "libc", 202 | "windows-sys 0.48.0", 203 | ] 204 | 205 | [[package]] 206 | name = "errno-dragonfly" 207 | version = "0.1.2" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 210 | dependencies = [ 211 | "cc", 212 | "libc", 213 | ] 214 | 215 | [[package]] 216 | name = "exr" 217 | version = "1.6.4" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "279d3efcc55e19917fff7ab3ddd6c14afb6a90881a0078465196fe2f99d08c56" 220 | dependencies = [ 221 | "bit_field", 222 | "flume", 223 | "half", 224 | "lebe", 225 | "miniz_oxide", 226 | "rayon-core", 227 | "smallvec", 228 | "zune-inflate", 229 | ] 230 | 231 | [[package]] 232 | name = "fastrand" 233 | version = "1.9.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 236 | dependencies = [ 237 | "instant", 238 | ] 239 | 240 | [[package]] 241 | name = "fdeflate" 242 | version = "0.3.0" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" 245 | dependencies = [ 246 | "simd-adler32", 247 | ] 248 | 249 | [[package]] 250 | name = "filetime" 251 | version = "0.2.21" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" 254 | dependencies = [ 255 | "cfg-if", 256 | "libc", 257 | "redox_syscall 0.2.16", 258 | "windows-sys 0.48.0", 259 | ] 260 | 261 | [[package]] 262 | name = "flate2" 263 | version = "1.0.26" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" 266 | dependencies = [ 267 | "crc32fast", 268 | "miniz_oxide", 269 | ] 270 | 271 | [[package]] 272 | name = "flume" 273 | version = "0.10.14" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" 276 | dependencies = [ 277 | "futures-core", 278 | "futures-sink", 279 | "nanorand", 280 | "pin-project", 281 | "spin 0.9.8", 282 | ] 283 | 284 | [[package]] 285 | name = "fnv" 286 | version = "1.0.7" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 289 | 290 | [[package]] 291 | name = "foreign-types" 292 | version = "0.3.2" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 295 | dependencies = [ 296 | "foreign-types-shared", 297 | ] 298 | 299 | [[package]] 300 | name = "foreign-types-shared" 301 | version = "0.1.1" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 304 | 305 | [[package]] 306 | name = "form_urlencoded" 307 | version = "1.2.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 310 | dependencies = [ 311 | "percent-encoding", 312 | ] 313 | 314 | [[package]] 315 | name = "futures-channel" 316 | version = "0.3.28" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 319 | dependencies = [ 320 | "futures-core", 321 | ] 322 | 323 | [[package]] 324 | name = "futures-core" 325 | version = "0.3.28" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 328 | 329 | [[package]] 330 | name = "futures-io" 331 | version = "0.3.28" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 334 | 335 | [[package]] 336 | name = "futures-sink" 337 | version = "0.3.28" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 340 | 341 | [[package]] 342 | name = "futures-task" 343 | version = "0.3.28" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 346 | 347 | [[package]] 348 | name = "futures-util" 349 | version = "0.3.28" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 352 | dependencies = [ 353 | "futures-core", 354 | "futures-io", 355 | "futures-task", 356 | "memchr", 357 | "pin-project-lite", 358 | "pin-utils", 359 | "slab", 360 | ] 361 | 362 | [[package]] 363 | name = "getrandom" 364 | version = "0.2.10" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 367 | dependencies = [ 368 | "cfg-if", 369 | "js-sys", 370 | "libc", 371 | "wasi", 372 | "wasm-bindgen", 373 | ] 374 | 375 | [[package]] 376 | name = "gif" 377 | version = "0.12.0" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" 380 | dependencies = [ 381 | "color_quant", 382 | "weezl", 383 | ] 384 | 385 | [[package]] 386 | name = "h2" 387 | version = "0.3.19" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" 390 | dependencies = [ 391 | "bytes", 392 | "fnv", 393 | "futures-core", 394 | "futures-sink", 395 | "futures-util", 396 | "http", 397 | "indexmap", 398 | "slab", 399 | "tokio", 400 | "tokio-util", 401 | "tracing", 402 | ] 403 | 404 | [[package]] 405 | name = "half" 406 | version = "2.2.1" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" 409 | dependencies = [ 410 | "crunchy", 411 | ] 412 | 413 | [[package]] 414 | name = "hashbrown" 415 | version = "0.12.3" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 418 | 419 | [[package]] 420 | name = "hermit-abi" 421 | version = "0.2.6" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 424 | dependencies = [ 425 | "libc", 426 | ] 427 | 428 | [[package]] 429 | name = "hermit-abi" 430 | version = "0.3.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 433 | 434 | [[package]] 435 | name = "home" 436 | version = "0.5.5" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" 439 | dependencies = [ 440 | "windows-sys 0.48.0", 441 | ] 442 | 443 | [[package]] 444 | name = "http" 445 | version = "0.2.9" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 448 | dependencies = [ 449 | "bytes", 450 | "fnv", 451 | "itoa", 452 | ] 453 | 454 | [[package]] 455 | name = "http-body" 456 | version = "0.4.5" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 459 | dependencies = [ 460 | "bytes", 461 | "http", 462 | "pin-project-lite", 463 | ] 464 | 465 | [[package]] 466 | name = "httparse" 467 | version = "1.8.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 470 | 471 | [[package]] 472 | name = "httpdate" 473 | version = "1.0.2" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 476 | 477 | [[package]] 478 | name = "hyper" 479 | version = "0.14.26" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" 482 | dependencies = [ 483 | "bytes", 484 | "futures-channel", 485 | "futures-core", 486 | "futures-util", 487 | "h2", 488 | "http", 489 | "http-body", 490 | "httparse", 491 | "httpdate", 492 | "itoa", 493 | "pin-project-lite", 494 | "socket2", 495 | "tokio", 496 | "tower-service", 497 | "tracing", 498 | "want", 499 | ] 500 | 501 | [[package]] 502 | name = "hyper-tls" 503 | version = "0.5.0" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 506 | dependencies = [ 507 | "bytes", 508 | "hyper", 509 | "native-tls", 510 | "tokio", 511 | "tokio-native-tls", 512 | ] 513 | 514 | [[package]] 515 | name = "idna" 516 | version = "0.4.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 519 | dependencies = [ 520 | "unicode-bidi", 521 | "unicode-normalization", 522 | ] 523 | 524 | [[package]] 525 | name = "image" 526 | version = "0.24.6" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" 529 | dependencies = [ 530 | "bytemuck", 531 | "byteorder", 532 | "color_quant", 533 | "exr", 534 | "gif", 535 | "jpeg-decoder", 536 | "num-rational", 537 | "num-traits", 538 | "png", 539 | "qoi", 540 | "tiff", 541 | ] 542 | 543 | [[package]] 544 | name = "indexmap" 545 | version = "1.9.3" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 548 | dependencies = [ 549 | "autocfg", 550 | "hashbrown", 551 | ] 552 | 553 | [[package]] 554 | name = "indicatif" 555 | version = "0.17.5" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" 558 | dependencies = [ 559 | "console", 560 | "instant", 561 | "number_prefix", 562 | "portable-atomic", 563 | "unicode-width", 564 | ] 565 | 566 | [[package]] 567 | name = "indoc" 568 | version = "1.0.9" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" 571 | 572 | [[package]] 573 | name = "instant" 574 | version = "0.1.12" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 577 | dependencies = [ 578 | "cfg-if", 579 | ] 580 | 581 | [[package]] 582 | name = "io-lifetimes" 583 | version = "1.0.11" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 586 | dependencies = [ 587 | "hermit-abi 0.3.1", 588 | "libc", 589 | "windows-sys 0.48.0", 590 | ] 591 | 592 | [[package]] 593 | name = "ipnet" 594 | version = "2.7.2" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" 597 | 598 | [[package]] 599 | name = "itertools" 600 | version = "0.11.0" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" 603 | dependencies = [ 604 | "either", 605 | ] 606 | 607 | [[package]] 608 | name = "itoa" 609 | version = "1.0.6" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 612 | 613 | [[package]] 614 | name = "jpeg-decoder" 615 | version = "0.3.0" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" 618 | dependencies = [ 619 | "rayon", 620 | ] 621 | 622 | [[package]] 623 | name = "js-sys" 624 | version = "0.3.64" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 627 | dependencies = [ 628 | "wasm-bindgen", 629 | ] 630 | 631 | [[package]] 632 | name = "lazy_static" 633 | version = "1.4.0" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 636 | 637 | [[package]] 638 | name = "lebe" 639 | version = "0.5.2" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 642 | 643 | [[package]] 644 | name = "libc" 645 | version = "0.2.146" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" 648 | 649 | [[package]] 650 | name = "libloading" 651 | version = "0.7.4" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 654 | dependencies = [ 655 | "cfg-if", 656 | "winapi", 657 | ] 658 | 659 | [[package]] 660 | name = "linux-raw-sys" 661 | version = "0.3.8" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 664 | 665 | [[package]] 666 | name = "lock_api" 667 | version = "0.4.10" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 670 | dependencies = [ 671 | "autocfg", 672 | "scopeguard", 673 | ] 674 | 675 | [[package]] 676 | name = "log" 677 | version = "0.4.19" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" 680 | 681 | [[package]] 682 | name = "matrixmultiply" 683 | version = "0.3.7" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" 686 | dependencies = [ 687 | "autocfg", 688 | "rawpointer", 689 | ] 690 | 691 | [[package]] 692 | name = "memchr" 693 | version = "2.5.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 696 | 697 | [[package]] 698 | name = "memoffset" 699 | version = "0.9.0" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 702 | dependencies = [ 703 | "autocfg", 704 | ] 705 | 706 | [[package]] 707 | name = "mime" 708 | version = "0.3.17" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 711 | 712 | [[package]] 713 | name = "miniz_oxide" 714 | version = "0.7.1" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 717 | dependencies = [ 718 | "adler", 719 | "simd-adler32", 720 | ] 721 | 722 | [[package]] 723 | name = "mio" 724 | version = "0.8.8" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 727 | dependencies = [ 728 | "libc", 729 | "wasi", 730 | "windows-sys 0.48.0", 731 | ] 732 | 733 | [[package]] 734 | name = "nalgebra" 735 | version = "0.30.1" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be" 738 | dependencies = [ 739 | "approx", 740 | "matrixmultiply", 741 | "num-complex", 742 | "num-rational", 743 | "num-traits", 744 | "simba", 745 | "typenum", 746 | ] 747 | 748 | [[package]] 749 | name = "nanorand" 750 | version = "0.7.0" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" 753 | dependencies = [ 754 | "getrandom", 755 | ] 756 | 757 | [[package]] 758 | name = "native-tls" 759 | version = "0.2.11" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 762 | dependencies = [ 763 | "lazy_static", 764 | "libc", 765 | "log", 766 | "openssl", 767 | "openssl-probe", 768 | "openssl-sys", 769 | "schannel", 770 | "security-framework", 771 | "security-framework-sys", 772 | "tempfile", 773 | ] 774 | 775 | [[package]] 776 | name = "ndarray" 777 | version = "0.15.6" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" 780 | dependencies = [ 781 | "matrixmultiply", 782 | "num-complex", 783 | "num-integer", 784 | "num-traits", 785 | "rawpointer", 786 | ] 787 | 788 | [[package]] 789 | name = "nshare" 790 | version = "0.9.0" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "4447657cd40e3107416ec4f2ac3e61a18781b00061789e3b8f4bbcbccb26c4c6" 793 | dependencies = [ 794 | "image", 795 | "nalgebra", 796 | "ndarray", 797 | ] 798 | 799 | [[package]] 800 | name = "num-complex" 801 | version = "0.4.3" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" 804 | dependencies = [ 805 | "num-traits", 806 | ] 807 | 808 | [[package]] 809 | name = "num-integer" 810 | version = "0.1.45" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 813 | dependencies = [ 814 | "autocfg", 815 | "num-traits", 816 | ] 817 | 818 | [[package]] 819 | name = "num-rational" 820 | version = "0.4.1" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 823 | dependencies = [ 824 | "autocfg", 825 | "num-integer", 826 | "num-traits", 827 | ] 828 | 829 | [[package]] 830 | name = "num-traits" 831 | version = "0.2.15" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 834 | dependencies = [ 835 | "autocfg", 836 | ] 837 | 838 | [[package]] 839 | name = "num_cpus" 840 | version = "1.15.0" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 843 | dependencies = [ 844 | "hermit-abi 0.2.6", 845 | "libc", 846 | ] 847 | 848 | [[package]] 849 | name = "number_prefix" 850 | version = "0.4.0" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 853 | 854 | [[package]] 855 | name = "numpy" 856 | version = "0.19.0" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "437213adf41bbccf4aeae535fbfcdad0f6fed241e1ae182ebe97fa1f3ce19389" 859 | dependencies = [ 860 | "libc", 861 | "ndarray", 862 | "num-complex", 863 | "num-integer", 864 | "num-traits", 865 | "pyo3", 866 | "rustc-hash", 867 | ] 868 | 869 | [[package]] 870 | name = "once_cell" 871 | version = "1.18.0" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 874 | 875 | [[package]] 876 | name = "openssl" 877 | version = "0.10.55" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" 880 | dependencies = [ 881 | "bitflags", 882 | "cfg-if", 883 | "foreign-types", 884 | "libc", 885 | "once_cell", 886 | "openssl-macros", 887 | "openssl-sys", 888 | ] 889 | 890 | [[package]] 891 | name = "openssl-macros" 892 | version = "0.1.1" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 895 | dependencies = [ 896 | "proc-macro2", 897 | "quote", 898 | "syn 2.0.18", 899 | ] 900 | 901 | [[package]] 902 | name = "openssl-probe" 903 | version = "0.1.5" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 906 | 907 | [[package]] 908 | name = "openssl-sys" 909 | version = "0.9.90" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" 912 | dependencies = [ 913 | "cc", 914 | "libc", 915 | "pkg-config", 916 | "vcpkg", 917 | ] 918 | 919 | [[package]] 920 | name = "ort" 921 | version = "1.14.8" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "562aedddfc14391badc2e527fd568164bd2fb108e2572cd3fe0b53ed440ec439" 924 | dependencies = [ 925 | "flate2", 926 | "half", 927 | "lazy_static", 928 | "libc", 929 | "libloading", 930 | "ndarray", 931 | "tar", 932 | "thiserror", 933 | "tracing", 934 | "ureq", 935 | "vswhom", 936 | "winapi", 937 | "zip", 938 | ] 939 | 940 | [[package]] 941 | name = "parking_lot" 942 | version = "0.12.1" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 945 | dependencies = [ 946 | "lock_api", 947 | "parking_lot_core", 948 | ] 949 | 950 | [[package]] 951 | name = "parking_lot_core" 952 | version = "0.9.8" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 955 | dependencies = [ 956 | "cfg-if", 957 | "libc", 958 | "redox_syscall 0.3.5", 959 | "smallvec", 960 | "windows-targets 0.48.0", 961 | ] 962 | 963 | [[package]] 964 | name = "paste" 965 | version = "1.0.12" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" 968 | 969 | [[package]] 970 | name = "percent-encoding" 971 | version = "2.3.0" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 974 | 975 | [[package]] 976 | name = "pin-project" 977 | version = "1.1.0" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" 980 | dependencies = [ 981 | "pin-project-internal", 982 | ] 983 | 984 | [[package]] 985 | name = "pin-project-internal" 986 | version = "1.1.0" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" 989 | dependencies = [ 990 | "proc-macro2", 991 | "quote", 992 | "syn 2.0.18", 993 | ] 994 | 995 | [[package]] 996 | name = "pin-project-lite" 997 | version = "0.2.9" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1000 | 1001 | [[package]] 1002 | name = "pin-utils" 1003 | version = "0.1.0" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1006 | 1007 | [[package]] 1008 | name = "pkg-config" 1009 | version = "0.3.27" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1012 | 1013 | [[package]] 1014 | name = "png" 1015 | version = "0.17.9" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" 1018 | dependencies = [ 1019 | "bitflags", 1020 | "crc32fast", 1021 | "fdeflate", 1022 | "flate2", 1023 | "miniz_oxide", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "portable-atomic" 1028 | version = "1.3.3" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" 1031 | 1032 | [[package]] 1033 | name = "proc-macro2" 1034 | version = "1.0.60" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" 1037 | dependencies = [ 1038 | "unicode-ident", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "py_rust_faces" 1043 | version = "0.3.0" 1044 | dependencies = [ 1045 | "image", 1046 | "numpy", 1047 | "pyo3", 1048 | "rust-faces", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "pyo3" 1053 | version = "0.19.0" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "cffef52f74ec3b1a1baf295d9b8fcc3070327aefc39a6d00656b13c1d0b8885c" 1056 | dependencies = [ 1057 | "cfg-if", 1058 | "indoc", 1059 | "libc", 1060 | "memoffset", 1061 | "parking_lot", 1062 | "pyo3-build-config", 1063 | "pyo3-ffi", 1064 | "pyo3-macros", 1065 | "unindent", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "pyo3-build-config" 1070 | version = "0.19.0" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "713eccf888fb05f1a96eb78c0dbc51907fee42b3377272dc902eb38985f418d5" 1073 | dependencies = [ 1074 | "once_cell", 1075 | "target-lexicon", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "pyo3-ffi" 1080 | version = "0.19.0" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "5b2ecbdcfb01cbbf56e179ce969a048fd7305a66d4cdf3303e0da09d69afe4c3" 1083 | dependencies = [ 1084 | "libc", 1085 | "pyo3-build-config", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "pyo3-macros" 1090 | version = "0.19.0" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "b78fdc0899f2ea781c463679b20cb08af9247febc8d052de941951024cd8aea0" 1093 | dependencies = [ 1094 | "proc-macro2", 1095 | "pyo3-macros-backend", 1096 | "quote", 1097 | "syn 1.0.109", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "pyo3-macros-backend" 1102 | version = "0.19.0" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "60da7b84f1227c3e2fe7593505de274dcf4c8928b4e0a1c23d551a14e4e80a0f" 1105 | dependencies = [ 1106 | "proc-macro2", 1107 | "quote", 1108 | "syn 1.0.109", 1109 | ] 1110 | 1111 | [[package]] 1112 | name = "qoi" 1113 | version = "0.4.1" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 1116 | dependencies = [ 1117 | "bytemuck", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "quote" 1122 | version = "1.0.28" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" 1125 | dependencies = [ 1126 | "proc-macro2", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "rawpointer" 1131 | version = "0.2.1" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 1134 | 1135 | [[package]] 1136 | name = "rayon" 1137 | version = "1.7.0" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" 1140 | dependencies = [ 1141 | "either", 1142 | "rayon-core", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "rayon-core" 1147 | version = "1.11.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" 1150 | dependencies = [ 1151 | "crossbeam-channel", 1152 | "crossbeam-deque", 1153 | "crossbeam-utils", 1154 | "num_cpus", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "redox_syscall" 1159 | version = "0.2.16" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1162 | dependencies = [ 1163 | "bitflags", 1164 | ] 1165 | 1166 | [[package]] 1167 | name = "redox_syscall" 1168 | version = "0.3.5" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1171 | dependencies = [ 1172 | "bitflags", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "reqwest" 1177 | version = "0.11.18" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" 1180 | dependencies = [ 1181 | "base64", 1182 | "bytes", 1183 | "encoding_rs", 1184 | "futures-core", 1185 | "futures-util", 1186 | "h2", 1187 | "http", 1188 | "http-body", 1189 | "hyper", 1190 | "hyper-tls", 1191 | "ipnet", 1192 | "js-sys", 1193 | "log", 1194 | "mime", 1195 | "native-tls", 1196 | "once_cell", 1197 | "percent-encoding", 1198 | "pin-project-lite", 1199 | "serde", 1200 | "serde_json", 1201 | "serde_urlencoded", 1202 | "tokio", 1203 | "tokio-native-tls", 1204 | "tower-service", 1205 | "url", 1206 | "wasm-bindgen", 1207 | "wasm-bindgen-futures", 1208 | "web-sys", 1209 | "winreg", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "ring" 1214 | version = "0.16.20" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1217 | dependencies = [ 1218 | "cc", 1219 | "libc", 1220 | "once_cell", 1221 | "spin 0.5.2", 1222 | "untrusted", 1223 | "web-sys", 1224 | "winapi", 1225 | ] 1226 | 1227 | [[package]] 1228 | name = "rust-faces" 1229 | version = "1.0.0" 1230 | dependencies = [ 1231 | "home", 1232 | "image", 1233 | "indicatif", 1234 | "itertools", 1235 | "ndarray", 1236 | "nshare", 1237 | "ort", 1238 | "reqwest", 1239 | "thiserror", 1240 | ] 1241 | 1242 | [[package]] 1243 | name = "rustc-hash" 1244 | version = "1.1.0" 1245 | source = "registry+https://github.com/rust-lang/crates.io-index" 1246 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1247 | 1248 | [[package]] 1249 | name = "rustix" 1250 | version = "0.37.20" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" 1253 | dependencies = [ 1254 | "bitflags", 1255 | "errno", 1256 | "io-lifetimes", 1257 | "libc", 1258 | "linux-raw-sys", 1259 | "windows-sys 0.48.0", 1260 | ] 1261 | 1262 | [[package]] 1263 | name = "rustls" 1264 | version = "0.21.2" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" 1267 | dependencies = [ 1268 | "log", 1269 | "ring", 1270 | "rustls-webpki", 1271 | "sct", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "rustls-webpki" 1276 | version = "0.100.1" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" 1279 | dependencies = [ 1280 | "ring", 1281 | "untrusted", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "ryu" 1286 | version = "1.0.13" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 1289 | 1290 | [[package]] 1291 | name = "safe_arch" 1292 | version = "0.7.0" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" 1295 | dependencies = [ 1296 | "bytemuck", 1297 | ] 1298 | 1299 | [[package]] 1300 | name = "schannel" 1301 | version = "0.1.21" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" 1304 | dependencies = [ 1305 | "windows-sys 0.42.0", 1306 | ] 1307 | 1308 | [[package]] 1309 | name = "scopeguard" 1310 | version = "1.1.0" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1313 | 1314 | [[package]] 1315 | name = "sct" 1316 | version = "0.7.0" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1319 | dependencies = [ 1320 | "ring", 1321 | "untrusted", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "security-framework" 1326 | version = "2.9.1" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" 1329 | dependencies = [ 1330 | "bitflags", 1331 | "core-foundation", 1332 | "core-foundation-sys", 1333 | "libc", 1334 | "security-framework-sys", 1335 | ] 1336 | 1337 | [[package]] 1338 | name = "security-framework-sys" 1339 | version = "2.9.0" 1340 | source = "registry+https://github.com/rust-lang/crates.io-index" 1341 | checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" 1342 | dependencies = [ 1343 | "core-foundation-sys", 1344 | "libc", 1345 | ] 1346 | 1347 | [[package]] 1348 | name = "serde" 1349 | version = "1.0.164" 1350 | source = "registry+https://github.com/rust-lang/crates.io-index" 1351 | checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" 1352 | 1353 | [[package]] 1354 | name = "serde_json" 1355 | version = "1.0.97" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" 1358 | dependencies = [ 1359 | "itoa", 1360 | "ryu", 1361 | "serde", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "serde_urlencoded" 1366 | version = "0.7.1" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1369 | dependencies = [ 1370 | "form_urlencoded", 1371 | "itoa", 1372 | "ryu", 1373 | "serde", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "simba" 1378 | version = "0.7.3" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176" 1381 | dependencies = [ 1382 | "approx", 1383 | "num-complex", 1384 | "num-traits", 1385 | "paste", 1386 | "wide", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "simd-adler32" 1391 | version = "0.3.5" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" 1394 | 1395 | [[package]] 1396 | name = "slab" 1397 | version = "0.4.8" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 1400 | dependencies = [ 1401 | "autocfg", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "smallvec" 1406 | version = "1.10.0" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1409 | 1410 | [[package]] 1411 | name = "socket2" 1412 | version = "0.4.9" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1415 | dependencies = [ 1416 | "libc", 1417 | "winapi", 1418 | ] 1419 | 1420 | [[package]] 1421 | name = "spin" 1422 | version = "0.5.2" 1423 | source = "registry+https://github.com/rust-lang/crates.io-index" 1424 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1425 | 1426 | [[package]] 1427 | name = "spin" 1428 | version = "0.9.8" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1431 | dependencies = [ 1432 | "lock_api", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "syn" 1437 | version = "1.0.109" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1440 | dependencies = [ 1441 | "proc-macro2", 1442 | "quote", 1443 | "unicode-ident", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "syn" 1448 | version = "2.0.18" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" 1451 | dependencies = [ 1452 | "proc-macro2", 1453 | "quote", 1454 | "unicode-ident", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "tar" 1459 | version = "0.4.38" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 1462 | dependencies = [ 1463 | "filetime", 1464 | "libc", 1465 | "xattr", 1466 | ] 1467 | 1468 | [[package]] 1469 | name = "target-lexicon" 1470 | version = "0.12.8" 1471 | source = "registry+https://github.com/rust-lang/crates.io-index" 1472 | checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac" 1473 | 1474 | [[package]] 1475 | name = "tempfile" 1476 | version = "3.6.0" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" 1479 | dependencies = [ 1480 | "autocfg", 1481 | "cfg-if", 1482 | "fastrand", 1483 | "redox_syscall 0.3.5", 1484 | "rustix", 1485 | "windows-sys 0.48.0", 1486 | ] 1487 | 1488 | [[package]] 1489 | name = "thiserror" 1490 | version = "1.0.40" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 1493 | dependencies = [ 1494 | "thiserror-impl", 1495 | ] 1496 | 1497 | [[package]] 1498 | name = "thiserror-impl" 1499 | version = "1.0.40" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 1502 | dependencies = [ 1503 | "proc-macro2", 1504 | "quote", 1505 | "syn 2.0.18", 1506 | ] 1507 | 1508 | [[package]] 1509 | name = "tiff" 1510 | version = "0.8.1" 1511 | source = "registry+https://github.com/rust-lang/crates.io-index" 1512 | checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" 1513 | dependencies = [ 1514 | "flate2", 1515 | "jpeg-decoder", 1516 | "weezl", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "tinyvec" 1521 | version = "1.6.0" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1524 | dependencies = [ 1525 | "tinyvec_macros", 1526 | ] 1527 | 1528 | [[package]] 1529 | name = "tinyvec_macros" 1530 | version = "0.1.1" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1533 | 1534 | [[package]] 1535 | name = "tokio" 1536 | version = "1.28.2" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" 1539 | dependencies = [ 1540 | "autocfg", 1541 | "bytes", 1542 | "libc", 1543 | "mio", 1544 | "num_cpus", 1545 | "pin-project-lite", 1546 | "socket2", 1547 | "windows-sys 0.48.0", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "tokio-native-tls" 1552 | version = "0.3.1" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1555 | dependencies = [ 1556 | "native-tls", 1557 | "tokio", 1558 | ] 1559 | 1560 | [[package]] 1561 | name = "tokio-util" 1562 | version = "0.7.8" 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" 1564 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1565 | dependencies = [ 1566 | "bytes", 1567 | "futures-core", 1568 | "futures-sink", 1569 | "pin-project-lite", 1570 | "tokio", 1571 | "tracing", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "tower-service" 1576 | version = "0.3.2" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1579 | 1580 | [[package]] 1581 | name = "tracing" 1582 | version = "0.1.37" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1585 | dependencies = [ 1586 | "cfg-if", 1587 | "pin-project-lite", 1588 | "tracing-attributes", 1589 | "tracing-core", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "tracing-attributes" 1594 | version = "0.1.26" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" 1597 | dependencies = [ 1598 | "proc-macro2", 1599 | "quote", 1600 | "syn 2.0.18", 1601 | ] 1602 | 1603 | [[package]] 1604 | name = "tracing-core" 1605 | version = "0.1.31" 1606 | source = "registry+https://github.com/rust-lang/crates.io-index" 1607 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1608 | dependencies = [ 1609 | "once_cell", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "try-lock" 1614 | version = "0.2.4" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1617 | 1618 | [[package]] 1619 | name = "typenum" 1620 | version = "1.16.0" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1623 | 1624 | [[package]] 1625 | name = "unicode-bidi" 1626 | version = "0.3.13" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1629 | 1630 | [[package]] 1631 | name = "unicode-ident" 1632 | version = "1.0.9" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" 1635 | 1636 | [[package]] 1637 | name = "unicode-normalization" 1638 | version = "0.1.22" 1639 | source = "registry+https://github.com/rust-lang/crates.io-index" 1640 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1641 | dependencies = [ 1642 | "tinyvec", 1643 | ] 1644 | 1645 | [[package]] 1646 | name = "unicode-width" 1647 | version = "0.1.10" 1648 | source = "registry+https://github.com/rust-lang/crates.io-index" 1649 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 1650 | 1651 | [[package]] 1652 | name = "unindent" 1653 | version = "0.1.11" 1654 | source = "registry+https://github.com/rust-lang/crates.io-index" 1655 | checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" 1656 | 1657 | [[package]] 1658 | name = "untrusted" 1659 | version = "0.7.1" 1660 | source = "registry+https://github.com/rust-lang/crates.io-index" 1661 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1662 | 1663 | [[package]] 1664 | name = "ureq" 1665 | version = "2.7.1" 1666 | source = "registry+https://github.com/rust-lang/crates.io-index" 1667 | checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" 1668 | dependencies = [ 1669 | "base64", 1670 | "log", 1671 | "once_cell", 1672 | "rustls", 1673 | "rustls-webpki", 1674 | "url", 1675 | "webpki-roots", 1676 | ] 1677 | 1678 | [[package]] 1679 | name = "url" 1680 | version = "2.4.0" 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" 1682 | checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" 1683 | dependencies = [ 1684 | "form_urlencoded", 1685 | "idna", 1686 | "percent-encoding", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "vcpkg" 1691 | version = "0.2.15" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1694 | 1695 | [[package]] 1696 | name = "vswhom" 1697 | version = "0.1.0" 1698 | source = "registry+https://github.com/rust-lang/crates.io-index" 1699 | checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" 1700 | dependencies = [ 1701 | "libc", 1702 | "vswhom-sys", 1703 | ] 1704 | 1705 | [[package]] 1706 | name = "vswhom-sys" 1707 | version = "0.1.2" 1708 | source = "registry+https://github.com/rust-lang/crates.io-index" 1709 | checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" 1710 | dependencies = [ 1711 | "cc", 1712 | "libc", 1713 | ] 1714 | 1715 | [[package]] 1716 | name = "want" 1717 | version = "0.3.1" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1720 | dependencies = [ 1721 | "try-lock", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "wasi" 1726 | version = "0.11.0+wasi-snapshot-preview1" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1729 | 1730 | [[package]] 1731 | name = "wasm-bindgen" 1732 | version = "0.2.87" 1733 | source = "registry+https://github.com/rust-lang/crates.io-index" 1734 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1735 | dependencies = [ 1736 | "cfg-if", 1737 | "wasm-bindgen-macro", 1738 | ] 1739 | 1740 | [[package]] 1741 | name = "wasm-bindgen-backend" 1742 | version = "0.2.87" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1745 | dependencies = [ 1746 | "bumpalo", 1747 | "log", 1748 | "once_cell", 1749 | "proc-macro2", 1750 | "quote", 1751 | "syn 2.0.18", 1752 | "wasm-bindgen-shared", 1753 | ] 1754 | 1755 | [[package]] 1756 | name = "wasm-bindgen-futures" 1757 | version = "0.4.37" 1758 | source = "registry+https://github.com/rust-lang/crates.io-index" 1759 | checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" 1760 | dependencies = [ 1761 | "cfg-if", 1762 | "js-sys", 1763 | "wasm-bindgen", 1764 | "web-sys", 1765 | ] 1766 | 1767 | [[package]] 1768 | name = "wasm-bindgen-macro" 1769 | version = "0.2.87" 1770 | source = "registry+https://github.com/rust-lang/crates.io-index" 1771 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1772 | dependencies = [ 1773 | "quote", 1774 | "wasm-bindgen-macro-support", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "wasm-bindgen-macro-support" 1779 | version = "0.2.87" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1782 | dependencies = [ 1783 | "proc-macro2", 1784 | "quote", 1785 | "syn 2.0.18", 1786 | "wasm-bindgen-backend", 1787 | "wasm-bindgen-shared", 1788 | ] 1789 | 1790 | [[package]] 1791 | name = "wasm-bindgen-shared" 1792 | version = "0.2.87" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1795 | 1796 | [[package]] 1797 | name = "web-sys" 1798 | version = "0.3.64" 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" 1800 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1801 | dependencies = [ 1802 | "js-sys", 1803 | "wasm-bindgen", 1804 | ] 1805 | 1806 | [[package]] 1807 | name = "webpki-roots" 1808 | version = "0.23.1" 1809 | source = "registry+https://github.com/rust-lang/crates.io-index" 1810 | checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" 1811 | dependencies = [ 1812 | "rustls-webpki", 1813 | ] 1814 | 1815 | [[package]] 1816 | name = "weezl" 1817 | version = "0.1.7" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" 1820 | 1821 | [[package]] 1822 | name = "wide" 1823 | version = "0.7.10" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" 1826 | dependencies = [ 1827 | "bytemuck", 1828 | "safe_arch", 1829 | ] 1830 | 1831 | [[package]] 1832 | name = "winapi" 1833 | version = "0.3.9" 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" 1835 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1836 | dependencies = [ 1837 | "winapi-i686-pc-windows-gnu", 1838 | "winapi-x86_64-pc-windows-gnu", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "winapi-i686-pc-windows-gnu" 1843 | version = "0.4.0" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1846 | 1847 | [[package]] 1848 | name = "winapi-x86_64-pc-windows-gnu" 1849 | version = "0.4.0" 1850 | source = "registry+https://github.com/rust-lang/crates.io-index" 1851 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1852 | 1853 | [[package]] 1854 | name = "windows-sys" 1855 | version = "0.42.0" 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" 1857 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1858 | dependencies = [ 1859 | "windows_aarch64_gnullvm 0.42.2", 1860 | "windows_aarch64_msvc 0.42.2", 1861 | "windows_i686_gnu 0.42.2", 1862 | "windows_i686_msvc 0.42.2", 1863 | "windows_x86_64_gnu 0.42.2", 1864 | "windows_x86_64_gnullvm 0.42.2", 1865 | "windows_x86_64_msvc 0.42.2", 1866 | ] 1867 | 1868 | [[package]] 1869 | name = "windows-sys" 1870 | version = "0.45.0" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1873 | dependencies = [ 1874 | "windows-targets 0.42.2", 1875 | ] 1876 | 1877 | [[package]] 1878 | name = "windows-sys" 1879 | version = "0.48.0" 1880 | source = "registry+https://github.com/rust-lang/crates.io-index" 1881 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1882 | dependencies = [ 1883 | "windows-targets 0.48.0", 1884 | ] 1885 | 1886 | [[package]] 1887 | name = "windows-targets" 1888 | version = "0.42.2" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1891 | dependencies = [ 1892 | "windows_aarch64_gnullvm 0.42.2", 1893 | "windows_aarch64_msvc 0.42.2", 1894 | "windows_i686_gnu 0.42.2", 1895 | "windows_i686_msvc 0.42.2", 1896 | "windows_x86_64_gnu 0.42.2", 1897 | "windows_x86_64_gnullvm 0.42.2", 1898 | "windows_x86_64_msvc 0.42.2", 1899 | ] 1900 | 1901 | [[package]] 1902 | name = "windows-targets" 1903 | version = "0.48.0" 1904 | source = "registry+https://github.com/rust-lang/crates.io-index" 1905 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 1906 | dependencies = [ 1907 | "windows_aarch64_gnullvm 0.48.0", 1908 | "windows_aarch64_msvc 0.48.0", 1909 | "windows_i686_gnu 0.48.0", 1910 | "windows_i686_msvc 0.48.0", 1911 | "windows_x86_64_gnu 0.48.0", 1912 | "windows_x86_64_gnullvm 0.48.0", 1913 | "windows_x86_64_msvc 0.48.0", 1914 | ] 1915 | 1916 | [[package]] 1917 | name = "windows_aarch64_gnullvm" 1918 | version = "0.42.2" 1919 | source = "registry+https://github.com/rust-lang/crates.io-index" 1920 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1921 | 1922 | [[package]] 1923 | name = "windows_aarch64_gnullvm" 1924 | version = "0.48.0" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 1927 | 1928 | [[package]] 1929 | name = "windows_aarch64_msvc" 1930 | version = "0.42.2" 1931 | source = "registry+https://github.com/rust-lang/crates.io-index" 1932 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1933 | 1934 | [[package]] 1935 | name = "windows_aarch64_msvc" 1936 | version = "0.48.0" 1937 | source = "registry+https://github.com/rust-lang/crates.io-index" 1938 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 1939 | 1940 | [[package]] 1941 | name = "windows_i686_gnu" 1942 | version = "0.42.2" 1943 | source = "registry+https://github.com/rust-lang/crates.io-index" 1944 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1945 | 1946 | [[package]] 1947 | name = "windows_i686_gnu" 1948 | version = "0.48.0" 1949 | source = "registry+https://github.com/rust-lang/crates.io-index" 1950 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 1951 | 1952 | [[package]] 1953 | name = "windows_i686_msvc" 1954 | version = "0.42.2" 1955 | source = "registry+https://github.com/rust-lang/crates.io-index" 1956 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1957 | 1958 | [[package]] 1959 | name = "windows_i686_msvc" 1960 | version = "0.48.0" 1961 | source = "registry+https://github.com/rust-lang/crates.io-index" 1962 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 1963 | 1964 | [[package]] 1965 | name = "windows_x86_64_gnu" 1966 | version = "0.42.2" 1967 | source = "registry+https://github.com/rust-lang/crates.io-index" 1968 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1969 | 1970 | [[package]] 1971 | name = "windows_x86_64_gnu" 1972 | version = "0.48.0" 1973 | source = "registry+https://github.com/rust-lang/crates.io-index" 1974 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 1975 | 1976 | [[package]] 1977 | name = "windows_x86_64_gnullvm" 1978 | version = "0.42.2" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1981 | 1982 | [[package]] 1983 | name = "windows_x86_64_gnullvm" 1984 | version = "0.48.0" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 1987 | 1988 | [[package]] 1989 | name = "windows_x86_64_msvc" 1990 | version = "0.42.2" 1991 | source = "registry+https://github.com/rust-lang/crates.io-index" 1992 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1993 | 1994 | [[package]] 1995 | name = "windows_x86_64_msvc" 1996 | version = "0.48.0" 1997 | source = "registry+https://github.com/rust-lang/crates.io-index" 1998 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 1999 | 2000 | [[package]] 2001 | name = "winreg" 2002 | version = "0.10.1" 2003 | source = "registry+https://github.com/rust-lang/crates.io-index" 2004 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 2005 | dependencies = [ 2006 | "winapi", 2007 | ] 2008 | 2009 | [[package]] 2010 | name = "xattr" 2011 | version = "0.2.3" 2012 | source = "registry+https://github.com/rust-lang/crates.io-index" 2013 | checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" 2014 | dependencies = [ 2015 | "libc", 2016 | ] 2017 | 2018 | [[package]] 2019 | name = "zip" 2020 | version = "0.6.6" 2021 | source = "registry+https://github.com/rust-lang/crates.io-index" 2022 | checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" 2023 | dependencies = [ 2024 | "byteorder", 2025 | "crc32fast", 2026 | "crossbeam-utils", 2027 | "flate2", 2028 | ] 2029 | 2030 | [[package]] 2031 | name = "zune-inflate" 2032 | version = "0.2.54" 2033 | source = "registry+https://github.com/rust-lang/crates.io-index" 2034 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 2035 | dependencies = [ 2036 | "simd-adler32", 2037 | ] 2038 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ab_glyph_rasterizer" 7 | version = "0.1.8" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" 10 | 11 | [[package]] 12 | name = "adler" 13 | version = "1.0.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 16 | 17 | [[package]] 18 | name = "anes" 19 | version = "0.1.6" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" 22 | 23 | [[package]] 24 | name = "approx" 25 | version = "0.5.1" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" 28 | dependencies = [ 29 | "num-traits", 30 | ] 31 | 32 | [[package]] 33 | name = "atty" 34 | version = "0.2.14" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 37 | dependencies = [ 38 | "hermit-abi 0.1.19", 39 | "libc", 40 | "winapi", 41 | ] 42 | 43 | [[package]] 44 | name = "autocfg" 45 | version = "1.1.0" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 48 | 49 | [[package]] 50 | name = "base64" 51 | version = "0.21.2" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" 54 | 55 | [[package]] 56 | name = "bit_field" 57 | version = "0.10.2" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 60 | 61 | [[package]] 62 | name = "bitflags" 63 | version = "1.3.2" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 66 | 67 | [[package]] 68 | name = "bumpalo" 69 | version = "3.13.0" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 72 | 73 | [[package]] 74 | name = "bytemuck" 75 | version = "1.13.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" 78 | 79 | [[package]] 80 | name = "byteorder" 81 | version = "1.4.3" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 84 | 85 | [[package]] 86 | name = "bytes" 87 | version = "1.4.0" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 90 | 91 | [[package]] 92 | name = "cast" 93 | version = "0.3.0" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" 96 | 97 | [[package]] 98 | name = "cc" 99 | version = "1.0.79" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 102 | 103 | [[package]] 104 | name = "cfg-if" 105 | version = "1.0.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 108 | 109 | [[package]] 110 | name = "ciborium" 111 | version = "0.2.1" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" 114 | dependencies = [ 115 | "ciborium-io", 116 | "ciborium-ll", 117 | "serde", 118 | ] 119 | 120 | [[package]] 121 | name = "ciborium-io" 122 | version = "0.2.1" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" 125 | 126 | [[package]] 127 | name = "ciborium-ll" 128 | version = "0.2.1" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" 131 | dependencies = [ 132 | "ciborium-io", 133 | "half 1.8.2", 134 | ] 135 | 136 | [[package]] 137 | name = "clap" 138 | version = "3.2.25" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" 141 | dependencies = [ 142 | "bitflags", 143 | "clap_lex", 144 | "indexmap", 145 | "textwrap", 146 | ] 147 | 148 | [[package]] 149 | name = "clap_lex" 150 | version = "0.2.4" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 153 | dependencies = [ 154 | "os_str_bytes", 155 | ] 156 | 157 | [[package]] 158 | name = "color_quant" 159 | version = "1.1.0" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 162 | 163 | [[package]] 164 | name = "console" 165 | version = "0.15.7" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" 168 | dependencies = [ 169 | "encode_unicode", 170 | "lazy_static", 171 | "libc", 172 | "unicode-width", 173 | "windows-sys 0.45.0", 174 | ] 175 | 176 | [[package]] 177 | name = "conv" 178 | version = "0.3.3" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" 181 | dependencies = [ 182 | "custom_derive", 183 | ] 184 | 185 | [[package]] 186 | name = "core-foundation" 187 | version = "0.9.3" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 190 | dependencies = [ 191 | "core-foundation-sys", 192 | "libc", 193 | ] 194 | 195 | [[package]] 196 | name = "core-foundation-sys" 197 | version = "0.8.4" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 200 | 201 | [[package]] 202 | name = "crc32fast" 203 | version = "1.3.2" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 206 | dependencies = [ 207 | "cfg-if", 208 | ] 209 | 210 | [[package]] 211 | name = "criterion" 212 | version = "0.4.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" 215 | dependencies = [ 216 | "anes", 217 | "atty", 218 | "cast", 219 | "ciborium", 220 | "clap", 221 | "criterion-plot", 222 | "itertools 0.10.5", 223 | "lazy_static", 224 | "num-traits", 225 | "oorandom", 226 | "plotters", 227 | "rayon", 228 | "regex", 229 | "serde", 230 | "serde_derive", 231 | "serde_json", 232 | "tinytemplate", 233 | "walkdir", 234 | ] 235 | 236 | [[package]] 237 | name = "criterion-plot" 238 | version = "0.5.0" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" 241 | dependencies = [ 242 | "cast", 243 | "itertools 0.10.5", 244 | ] 245 | 246 | [[package]] 247 | name = "crossbeam-channel" 248 | version = "0.5.8" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" 251 | dependencies = [ 252 | "cfg-if", 253 | "crossbeam-utils", 254 | ] 255 | 256 | [[package]] 257 | name = "crossbeam-deque" 258 | version = "0.8.3" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" 261 | dependencies = [ 262 | "cfg-if", 263 | "crossbeam-epoch", 264 | "crossbeam-utils", 265 | ] 266 | 267 | [[package]] 268 | name = "crossbeam-epoch" 269 | version = "0.9.15" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" 272 | dependencies = [ 273 | "autocfg", 274 | "cfg-if", 275 | "crossbeam-utils", 276 | "memoffset", 277 | "scopeguard", 278 | ] 279 | 280 | [[package]] 281 | name = "crossbeam-utils" 282 | version = "0.8.16" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" 285 | dependencies = [ 286 | "cfg-if", 287 | ] 288 | 289 | [[package]] 290 | name = "crunchy" 291 | version = "0.2.2" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 294 | 295 | [[package]] 296 | name = "custom_derive" 297 | version = "0.1.7" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" 300 | 301 | [[package]] 302 | name = "either" 303 | version = "1.8.1" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" 306 | 307 | [[package]] 308 | name = "encode_unicode" 309 | version = "0.3.6" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 312 | 313 | [[package]] 314 | name = "encoding_rs" 315 | version = "0.8.32" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" 318 | dependencies = [ 319 | "cfg-if", 320 | ] 321 | 322 | [[package]] 323 | name = "errno" 324 | version = "0.3.1" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" 327 | dependencies = [ 328 | "errno-dragonfly", 329 | "libc", 330 | "windows-sys 0.48.0", 331 | ] 332 | 333 | [[package]] 334 | name = "errno-dragonfly" 335 | version = "0.1.2" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 338 | dependencies = [ 339 | "cc", 340 | "libc", 341 | ] 342 | 343 | [[package]] 344 | name = "exr" 345 | version = "1.6.4" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "279d3efcc55e19917fff7ab3ddd6c14afb6a90881a0078465196fe2f99d08c56" 348 | dependencies = [ 349 | "bit_field", 350 | "flume", 351 | "half 2.2.1", 352 | "lebe", 353 | "miniz_oxide", 354 | "rayon-core", 355 | "smallvec", 356 | "zune-inflate", 357 | ] 358 | 359 | [[package]] 360 | name = "fastrand" 361 | version = "1.9.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 364 | dependencies = [ 365 | "instant", 366 | ] 367 | 368 | [[package]] 369 | name = "fdeflate" 370 | version = "0.3.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" 373 | dependencies = [ 374 | "simd-adler32", 375 | ] 376 | 377 | [[package]] 378 | name = "filetime" 379 | version = "0.2.21" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" 382 | dependencies = [ 383 | "cfg-if", 384 | "libc", 385 | "redox_syscall 0.2.16", 386 | "windows-sys 0.48.0", 387 | ] 388 | 389 | [[package]] 390 | name = "flate2" 391 | version = "1.0.26" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" 394 | dependencies = [ 395 | "crc32fast", 396 | "miniz_oxide", 397 | ] 398 | 399 | [[package]] 400 | name = "flume" 401 | version = "0.10.14" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" 404 | dependencies = [ 405 | "futures-core", 406 | "futures-sink", 407 | "nanorand", 408 | "pin-project", 409 | "spin 0.9.8", 410 | ] 411 | 412 | [[package]] 413 | name = "fnv" 414 | version = "1.0.7" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 417 | 418 | [[package]] 419 | name = "foreign-types" 420 | version = "0.3.2" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 423 | dependencies = [ 424 | "foreign-types-shared", 425 | ] 426 | 427 | [[package]] 428 | name = "foreign-types-shared" 429 | version = "0.1.1" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 432 | 433 | [[package]] 434 | name = "form_urlencoded" 435 | version = "1.2.0" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 438 | dependencies = [ 439 | "percent-encoding", 440 | ] 441 | 442 | [[package]] 443 | name = "futures" 444 | version = "0.3.28" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 447 | dependencies = [ 448 | "futures-channel", 449 | "futures-core", 450 | "futures-executor", 451 | "futures-io", 452 | "futures-sink", 453 | "futures-task", 454 | "futures-util", 455 | ] 456 | 457 | [[package]] 458 | name = "futures-channel" 459 | version = "0.3.28" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 462 | dependencies = [ 463 | "futures-core", 464 | "futures-sink", 465 | ] 466 | 467 | [[package]] 468 | name = "futures-core" 469 | version = "0.3.28" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 472 | 473 | [[package]] 474 | name = "futures-executor" 475 | version = "0.3.28" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 478 | dependencies = [ 479 | "futures-core", 480 | "futures-task", 481 | "futures-util", 482 | ] 483 | 484 | [[package]] 485 | name = "futures-io" 486 | version = "0.3.28" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 489 | 490 | [[package]] 491 | name = "futures-macro" 492 | version = "0.3.28" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 495 | dependencies = [ 496 | "proc-macro2", 497 | "quote", 498 | "syn 2.0.18", 499 | ] 500 | 501 | [[package]] 502 | name = "futures-sink" 503 | version = "0.3.28" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 506 | 507 | [[package]] 508 | name = "futures-task" 509 | version = "0.3.28" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 512 | 513 | [[package]] 514 | name = "futures-timer" 515 | version = "3.0.2" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" 518 | 519 | [[package]] 520 | name = "futures-util" 521 | version = "0.3.28" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 524 | dependencies = [ 525 | "futures-channel", 526 | "futures-core", 527 | "futures-io", 528 | "futures-macro", 529 | "futures-sink", 530 | "futures-task", 531 | "memchr", 532 | "pin-project-lite", 533 | "pin-utils", 534 | "slab", 535 | ] 536 | 537 | [[package]] 538 | name = "getrandom" 539 | version = "0.1.16" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 542 | dependencies = [ 543 | "cfg-if", 544 | "libc", 545 | "wasi 0.9.0+wasi-snapshot-preview1", 546 | ] 547 | 548 | [[package]] 549 | name = "getrandom" 550 | version = "0.2.10" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 553 | dependencies = [ 554 | "cfg-if", 555 | "js-sys", 556 | "libc", 557 | "wasi 0.11.0+wasi-snapshot-preview1", 558 | "wasm-bindgen", 559 | ] 560 | 561 | [[package]] 562 | name = "gif" 563 | version = "0.12.0" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" 566 | dependencies = [ 567 | "color_quant", 568 | "weezl", 569 | ] 570 | 571 | [[package]] 572 | name = "h2" 573 | version = "0.3.19" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" 576 | dependencies = [ 577 | "bytes", 578 | "fnv", 579 | "futures-core", 580 | "futures-sink", 581 | "futures-util", 582 | "http", 583 | "indexmap", 584 | "slab", 585 | "tokio", 586 | "tokio-util", 587 | "tracing", 588 | ] 589 | 590 | [[package]] 591 | name = "half" 592 | version = "1.8.2" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" 595 | 596 | [[package]] 597 | name = "half" 598 | version = "2.2.1" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" 601 | dependencies = [ 602 | "crunchy", 603 | ] 604 | 605 | [[package]] 606 | name = "hashbrown" 607 | version = "0.12.3" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 610 | 611 | [[package]] 612 | name = "hermit-abi" 613 | version = "0.1.19" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 616 | dependencies = [ 617 | "libc", 618 | ] 619 | 620 | [[package]] 621 | name = "hermit-abi" 622 | version = "0.2.6" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 625 | dependencies = [ 626 | "libc", 627 | ] 628 | 629 | [[package]] 630 | name = "hermit-abi" 631 | version = "0.3.1" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 634 | 635 | [[package]] 636 | name = "home" 637 | version = "0.5.5" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" 640 | dependencies = [ 641 | "windows-sys 0.48.0", 642 | ] 643 | 644 | [[package]] 645 | name = "http" 646 | version = "0.2.9" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 649 | dependencies = [ 650 | "bytes", 651 | "fnv", 652 | "itoa", 653 | ] 654 | 655 | [[package]] 656 | name = "http-body" 657 | version = "0.4.5" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 660 | dependencies = [ 661 | "bytes", 662 | "http", 663 | "pin-project-lite", 664 | ] 665 | 666 | [[package]] 667 | name = "httparse" 668 | version = "1.8.0" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 671 | 672 | [[package]] 673 | name = "httpdate" 674 | version = "1.0.2" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 677 | 678 | [[package]] 679 | name = "hyper" 680 | version = "0.14.26" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" 683 | dependencies = [ 684 | "bytes", 685 | "futures-channel", 686 | "futures-core", 687 | "futures-util", 688 | "h2", 689 | "http", 690 | "http-body", 691 | "httparse", 692 | "httpdate", 693 | "itoa", 694 | "pin-project-lite", 695 | "socket2", 696 | "tokio", 697 | "tower-service", 698 | "tracing", 699 | "want", 700 | ] 701 | 702 | [[package]] 703 | name = "hyper-tls" 704 | version = "0.5.0" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 707 | dependencies = [ 708 | "bytes", 709 | "hyper", 710 | "native-tls", 711 | "tokio", 712 | "tokio-native-tls", 713 | ] 714 | 715 | [[package]] 716 | name = "idna" 717 | version = "0.4.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 720 | dependencies = [ 721 | "unicode-bidi", 722 | "unicode-normalization", 723 | ] 724 | 725 | [[package]] 726 | name = "image" 727 | version = "0.24.6" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" 730 | dependencies = [ 731 | "bytemuck", 732 | "byteorder", 733 | "color_quant", 734 | "exr", 735 | "gif", 736 | "jpeg-decoder", 737 | "num-rational", 738 | "num-traits", 739 | "png", 740 | "qoi", 741 | "tiff", 742 | ] 743 | 744 | [[package]] 745 | name = "imageproc" 746 | version = "0.23.0" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7" 749 | dependencies = [ 750 | "approx", 751 | "conv", 752 | "image", 753 | "itertools 0.10.5", 754 | "nalgebra", 755 | "num", 756 | "rand", 757 | "rand_distr", 758 | "rayon", 759 | "rusttype", 760 | ] 761 | 762 | [[package]] 763 | name = "indexmap" 764 | version = "1.9.3" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 767 | dependencies = [ 768 | "autocfg", 769 | "hashbrown", 770 | ] 771 | 772 | [[package]] 773 | name = "indicatif" 774 | version = "0.17.5" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" 777 | dependencies = [ 778 | "console", 779 | "instant", 780 | "number_prefix", 781 | "portable-atomic", 782 | "unicode-width", 783 | ] 784 | 785 | [[package]] 786 | name = "instant" 787 | version = "0.1.12" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 790 | dependencies = [ 791 | "cfg-if", 792 | ] 793 | 794 | [[package]] 795 | name = "io-lifetimes" 796 | version = "1.0.11" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 799 | dependencies = [ 800 | "hermit-abi 0.3.1", 801 | "libc", 802 | "windows-sys 0.48.0", 803 | ] 804 | 805 | [[package]] 806 | name = "ipnet" 807 | version = "2.7.2" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" 810 | 811 | [[package]] 812 | name = "itertools" 813 | version = "0.10.5" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 816 | dependencies = [ 817 | "either", 818 | ] 819 | 820 | [[package]] 821 | name = "itertools" 822 | version = "0.11.0" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" 825 | dependencies = [ 826 | "either", 827 | ] 828 | 829 | [[package]] 830 | name = "itoa" 831 | version = "1.0.6" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 834 | 835 | [[package]] 836 | name = "jpeg-decoder" 837 | version = "0.3.0" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" 840 | dependencies = [ 841 | "rayon", 842 | ] 843 | 844 | [[package]] 845 | name = "js-sys" 846 | version = "0.3.64" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 849 | dependencies = [ 850 | "wasm-bindgen", 851 | ] 852 | 853 | [[package]] 854 | name = "lazy_static" 855 | version = "1.4.0" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 858 | 859 | [[package]] 860 | name = "lebe" 861 | version = "0.5.2" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 864 | 865 | [[package]] 866 | name = "libc" 867 | version = "0.2.146" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" 870 | 871 | [[package]] 872 | name = "libloading" 873 | version = "0.7.4" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 876 | dependencies = [ 877 | "cfg-if", 878 | "winapi", 879 | ] 880 | 881 | [[package]] 882 | name = "linux-raw-sys" 883 | version = "0.3.8" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 886 | 887 | [[package]] 888 | name = "lock_api" 889 | version = "0.4.10" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 892 | dependencies = [ 893 | "autocfg", 894 | "scopeguard", 895 | ] 896 | 897 | [[package]] 898 | name = "log" 899 | version = "0.4.19" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" 902 | 903 | [[package]] 904 | name = "matrixmultiply" 905 | version = "0.3.7" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" 908 | dependencies = [ 909 | "autocfg", 910 | "rawpointer", 911 | ] 912 | 913 | [[package]] 914 | name = "memchr" 915 | version = "2.5.0" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 918 | 919 | [[package]] 920 | name = "memoffset" 921 | version = "0.9.0" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 924 | dependencies = [ 925 | "autocfg", 926 | ] 927 | 928 | [[package]] 929 | name = "mime" 930 | version = "0.3.17" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 933 | 934 | [[package]] 935 | name = "miniz_oxide" 936 | version = "0.7.1" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 939 | dependencies = [ 940 | "adler", 941 | "simd-adler32", 942 | ] 943 | 944 | [[package]] 945 | name = "mio" 946 | version = "0.8.8" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 949 | dependencies = [ 950 | "libc", 951 | "wasi 0.11.0+wasi-snapshot-preview1", 952 | "windows-sys 0.48.0", 953 | ] 954 | 955 | [[package]] 956 | name = "nalgebra" 957 | version = "0.30.1" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be" 960 | dependencies = [ 961 | "approx", 962 | "matrixmultiply", 963 | "num-complex", 964 | "num-rational", 965 | "num-traits", 966 | "simba", 967 | "typenum", 968 | ] 969 | 970 | [[package]] 971 | name = "nanorand" 972 | version = "0.7.0" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" 975 | dependencies = [ 976 | "getrandom 0.2.10", 977 | ] 978 | 979 | [[package]] 980 | name = "native-tls" 981 | version = "0.2.11" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 984 | dependencies = [ 985 | "lazy_static", 986 | "libc", 987 | "log", 988 | "openssl", 989 | "openssl-probe", 990 | "openssl-sys", 991 | "schannel", 992 | "security-framework", 993 | "security-framework-sys", 994 | "tempfile", 995 | ] 996 | 997 | [[package]] 998 | name = "ndarray" 999 | version = "0.15.6" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" 1002 | dependencies = [ 1003 | "matrixmultiply", 1004 | "num-complex", 1005 | "num-integer", 1006 | "num-traits", 1007 | "rawpointer", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "nshare" 1012 | version = "0.9.0" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "4447657cd40e3107416ec4f2ac3e61a18781b00061789e3b8f4bbcbccb26c4c6" 1015 | dependencies = [ 1016 | "image", 1017 | "nalgebra", 1018 | "ndarray", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "num" 1023 | version = "0.4.0" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" 1026 | dependencies = [ 1027 | "num-bigint", 1028 | "num-complex", 1029 | "num-integer", 1030 | "num-iter", 1031 | "num-rational", 1032 | "num-traits", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "num-bigint" 1037 | version = "0.4.3" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" 1040 | dependencies = [ 1041 | "autocfg", 1042 | "num-integer", 1043 | "num-traits", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "num-complex" 1048 | version = "0.4.3" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" 1051 | dependencies = [ 1052 | "num-traits", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "num-integer" 1057 | version = "0.1.45" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1060 | dependencies = [ 1061 | "autocfg", 1062 | "num-traits", 1063 | ] 1064 | 1065 | [[package]] 1066 | name = "num-iter" 1067 | version = "0.1.43" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" 1070 | dependencies = [ 1071 | "autocfg", 1072 | "num-integer", 1073 | "num-traits", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "num-rational" 1078 | version = "0.4.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 1081 | dependencies = [ 1082 | "autocfg", 1083 | "num-bigint", 1084 | "num-integer", 1085 | "num-traits", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "num-traits" 1090 | version = "0.2.15" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1093 | dependencies = [ 1094 | "autocfg", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "num_cpus" 1099 | version = "1.15.0" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 1102 | dependencies = [ 1103 | "hermit-abi 0.2.6", 1104 | "libc", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "number_prefix" 1109 | version = "0.4.0" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 1112 | 1113 | [[package]] 1114 | name = "once_cell" 1115 | version = "1.18.0" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 1118 | 1119 | [[package]] 1120 | name = "oorandom" 1121 | version = "11.1.3" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" 1124 | 1125 | [[package]] 1126 | name = "openssl" 1127 | version = "0.10.55" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" 1130 | dependencies = [ 1131 | "bitflags", 1132 | "cfg-if", 1133 | "foreign-types", 1134 | "libc", 1135 | "once_cell", 1136 | "openssl-macros", 1137 | "openssl-sys", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "openssl-macros" 1142 | version = "0.1.1" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1145 | dependencies = [ 1146 | "proc-macro2", 1147 | "quote", 1148 | "syn 2.0.18", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "openssl-probe" 1153 | version = "0.1.5" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1156 | 1157 | [[package]] 1158 | name = "openssl-sys" 1159 | version = "0.9.90" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" 1162 | dependencies = [ 1163 | "cc", 1164 | "libc", 1165 | "pkg-config", 1166 | "vcpkg", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "ort" 1171 | version = "1.15.2" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "c5e56c9c4185ee949ef961aca8777d1dbd52cb104b444669adad63e8181820a7" 1174 | dependencies = [ 1175 | "flate2", 1176 | "half 2.2.1", 1177 | "lazy_static", 1178 | "libc", 1179 | "libloading", 1180 | "ndarray", 1181 | "tar", 1182 | "thiserror", 1183 | "tracing", 1184 | "ureq", 1185 | "vswhom", 1186 | "winapi", 1187 | "zip", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "os_str_bytes" 1192 | version = "6.5.1" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" 1195 | 1196 | [[package]] 1197 | name = "owned_ttf_parser" 1198 | version = "0.15.2" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" 1201 | dependencies = [ 1202 | "ttf-parser", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "paste" 1207 | version = "1.0.12" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" 1210 | 1211 | [[package]] 1212 | name = "percent-encoding" 1213 | version = "2.3.0" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 1216 | 1217 | [[package]] 1218 | name = "pin-project" 1219 | version = "1.1.0" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" 1222 | dependencies = [ 1223 | "pin-project-internal", 1224 | ] 1225 | 1226 | [[package]] 1227 | name = "pin-project-internal" 1228 | version = "1.1.0" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" 1231 | dependencies = [ 1232 | "proc-macro2", 1233 | "quote", 1234 | "syn 2.0.18", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "pin-project-lite" 1239 | version = "0.2.9" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1242 | 1243 | [[package]] 1244 | name = "pin-utils" 1245 | version = "0.1.0" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1248 | 1249 | [[package]] 1250 | name = "pkg-config" 1251 | version = "0.3.27" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1254 | 1255 | [[package]] 1256 | name = "plotters" 1257 | version = "0.3.5" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" 1260 | dependencies = [ 1261 | "num-traits", 1262 | "plotters-backend", 1263 | "plotters-svg", 1264 | "wasm-bindgen", 1265 | "web-sys", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "plotters-backend" 1270 | version = "0.3.5" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" 1273 | 1274 | [[package]] 1275 | name = "plotters-svg" 1276 | version = "0.3.5" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" 1279 | dependencies = [ 1280 | "plotters-backend", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "png" 1285 | version = "0.17.9" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" 1288 | dependencies = [ 1289 | "bitflags", 1290 | "crc32fast", 1291 | "fdeflate", 1292 | "flate2", 1293 | "miniz_oxide", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "portable-atomic" 1298 | version = "1.3.3" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" 1301 | 1302 | [[package]] 1303 | name = "ppv-lite86" 1304 | version = "0.2.17" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1307 | 1308 | [[package]] 1309 | name = "proc-macro2" 1310 | version = "1.0.60" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" 1313 | dependencies = [ 1314 | "unicode-ident", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "qoi" 1319 | version = "0.4.1" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 1322 | dependencies = [ 1323 | "bytemuck", 1324 | ] 1325 | 1326 | [[package]] 1327 | name = "quote" 1328 | version = "1.0.28" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" 1331 | dependencies = [ 1332 | "proc-macro2", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "rand" 1337 | version = "0.7.3" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1340 | dependencies = [ 1341 | "getrandom 0.1.16", 1342 | "libc", 1343 | "rand_chacha", 1344 | "rand_core", 1345 | "rand_hc", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "rand_chacha" 1350 | version = "0.2.2" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1353 | dependencies = [ 1354 | "ppv-lite86", 1355 | "rand_core", 1356 | ] 1357 | 1358 | [[package]] 1359 | name = "rand_core" 1360 | version = "0.5.1" 1361 | source = "registry+https://github.com/rust-lang/crates.io-index" 1362 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1363 | dependencies = [ 1364 | "getrandom 0.1.16", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "rand_distr" 1369 | version = "0.2.2" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" 1372 | dependencies = [ 1373 | "rand", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "rand_hc" 1378 | version = "0.2.0" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1381 | dependencies = [ 1382 | "rand_core", 1383 | ] 1384 | 1385 | [[package]] 1386 | name = "rawpointer" 1387 | version = "0.2.1" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 1390 | 1391 | [[package]] 1392 | name = "rayon" 1393 | version = "1.7.0" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" 1396 | dependencies = [ 1397 | "either", 1398 | "rayon-core", 1399 | ] 1400 | 1401 | [[package]] 1402 | name = "rayon-core" 1403 | version = "1.11.0" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" 1406 | dependencies = [ 1407 | "crossbeam-channel", 1408 | "crossbeam-deque", 1409 | "crossbeam-utils", 1410 | "num_cpus", 1411 | ] 1412 | 1413 | [[package]] 1414 | name = "redox_syscall" 1415 | version = "0.2.16" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1418 | dependencies = [ 1419 | "bitflags", 1420 | ] 1421 | 1422 | [[package]] 1423 | name = "redox_syscall" 1424 | version = "0.3.5" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1427 | dependencies = [ 1428 | "bitflags", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "regex" 1433 | version = "1.8.4" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" 1436 | dependencies = [ 1437 | "regex-syntax", 1438 | ] 1439 | 1440 | [[package]] 1441 | name = "regex-syntax" 1442 | version = "0.7.2" 1443 | source = "registry+https://github.com/rust-lang/crates.io-index" 1444 | checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" 1445 | 1446 | [[package]] 1447 | name = "reqwest" 1448 | version = "0.11.18" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" 1451 | dependencies = [ 1452 | "base64", 1453 | "bytes", 1454 | "encoding_rs", 1455 | "futures-core", 1456 | "futures-util", 1457 | "h2", 1458 | "http", 1459 | "http-body", 1460 | "hyper", 1461 | "hyper-tls", 1462 | "ipnet", 1463 | "js-sys", 1464 | "log", 1465 | "mime", 1466 | "native-tls", 1467 | "once_cell", 1468 | "percent-encoding", 1469 | "pin-project-lite", 1470 | "serde", 1471 | "serde_json", 1472 | "serde_urlencoded", 1473 | "tokio", 1474 | "tokio-native-tls", 1475 | "tower-service", 1476 | "url", 1477 | "wasm-bindgen", 1478 | "wasm-bindgen-futures", 1479 | "web-sys", 1480 | "winreg", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "ring" 1485 | version = "0.16.20" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1488 | dependencies = [ 1489 | "cc", 1490 | "libc", 1491 | "once_cell", 1492 | "spin 0.5.2", 1493 | "untrusted", 1494 | "web-sys", 1495 | "winapi", 1496 | ] 1497 | 1498 | [[package]] 1499 | name = "rstest" 1500 | version = "0.17.0" 1501 | source = "registry+https://github.com/rust-lang/crates.io-index" 1502 | checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" 1503 | dependencies = [ 1504 | "futures", 1505 | "futures-timer", 1506 | "rstest_macros", 1507 | "rustc_version", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "rstest_macros" 1512 | version = "0.17.0" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" 1515 | dependencies = [ 1516 | "cfg-if", 1517 | "proc-macro2", 1518 | "quote", 1519 | "rustc_version", 1520 | "syn 1.0.109", 1521 | "unicode-ident", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "rust-faces" 1526 | version = "1.0.0" 1527 | dependencies = [ 1528 | "criterion", 1529 | "home", 1530 | "image", 1531 | "imageproc", 1532 | "indicatif", 1533 | "itertools 0.11.0", 1534 | "ndarray", 1535 | "nshare", 1536 | "ort", 1537 | "reqwest", 1538 | "rstest", 1539 | "thiserror", 1540 | ] 1541 | 1542 | [[package]] 1543 | name = "rustc_version" 1544 | version = "0.4.0" 1545 | source = "registry+https://github.com/rust-lang/crates.io-index" 1546 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1547 | dependencies = [ 1548 | "semver", 1549 | ] 1550 | 1551 | [[package]] 1552 | name = "rustix" 1553 | version = "0.37.20" 1554 | source = "registry+https://github.com/rust-lang/crates.io-index" 1555 | checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" 1556 | dependencies = [ 1557 | "bitflags", 1558 | "errno", 1559 | "io-lifetimes", 1560 | "libc", 1561 | "linux-raw-sys", 1562 | "windows-sys 0.48.0", 1563 | ] 1564 | 1565 | [[package]] 1566 | name = "rustls" 1567 | version = "0.21.2" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" 1570 | dependencies = [ 1571 | "log", 1572 | "ring", 1573 | "rustls-webpki", 1574 | "sct", 1575 | ] 1576 | 1577 | [[package]] 1578 | name = "rustls-webpki" 1579 | version = "0.100.1" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" 1582 | dependencies = [ 1583 | "ring", 1584 | "untrusted", 1585 | ] 1586 | 1587 | [[package]] 1588 | name = "rusttype" 1589 | version = "0.9.3" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967" 1592 | dependencies = [ 1593 | "ab_glyph_rasterizer", 1594 | "owned_ttf_parser", 1595 | ] 1596 | 1597 | [[package]] 1598 | name = "ryu" 1599 | version = "1.0.13" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 1602 | 1603 | [[package]] 1604 | name = "safe_arch" 1605 | version = "0.7.0" 1606 | source = "registry+https://github.com/rust-lang/crates.io-index" 1607 | checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" 1608 | dependencies = [ 1609 | "bytemuck", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "same-file" 1614 | version = "1.0.6" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1617 | dependencies = [ 1618 | "winapi-util", 1619 | ] 1620 | 1621 | [[package]] 1622 | name = "schannel" 1623 | version = "0.1.21" 1624 | source = "registry+https://github.com/rust-lang/crates.io-index" 1625 | checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" 1626 | dependencies = [ 1627 | "windows-sys 0.42.0", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "scopeguard" 1632 | version = "1.1.0" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1635 | 1636 | [[package]] 1637 | name = "sct" 1638 | version = "0.7.0" 1639 | source = "registry+https://github.com/rust-lang/crates.io-index" 1640 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1641 | dependencies = [ 1642 | "ring", 1643 | "untrusted", 1644 | ] 1645 | 1646 | [[package]] 1647 | name = "security-framework" 1648 | version = "2.9.1" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" 1651 | dependencies = [ 1652 | "bitflags", 1653 | "core-foundation", 1654 | "core-foundation-sys", 1655 | "libc", 1656 | "security-framework-sys", 1657 | ] 1658 | 1659 | [[package]] 1660 | name = "security-framework-sys" 1661 | version = "2.9.0" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" 1664 | dependencies = [ 1665 | "core-foundation-sys", 1666 | "libc", 1667 | ] 1668 | 1669 | [[package]] 1670 | name = "semver" 1671 | version = "1.0.17" 1672 | source = "registry+https://github.com/rust-lang/crates.io-index" 1673 | checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" 1674 | 1675 | [[package]] 1676 | name = "serde" 1677 | version = "1.0.164" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" 1680 | dependencies = [ 1681 | "serde_derive", 1682 | ] 1683 | 1684 | [[package]] 1685 | name = "serde_derive" 1686 | version = "1.0.164" 1687 | source = "registry+https://github.com/rust-lang/crates.io-index" 1688 | checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" 1689 | dependencies = [ 1690 | "proc-macro2", 1691 | "quote", 1692 | "syn 2.0.18", 1693 | ] 1694 | 1695 | [[package]] 1696 | name = "serde_json" 1697 | version = "1.0.97" 1698 | source = "registry+https://github.com/rust-lang/crates.io-index" 1699 | checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" 1700 | dependencies = [ 1701 | "itoa", 1702 | "ryu", 1703 | "serde", 1704 | ] 1705 | 1706 | [[package]] 1707 | name = "serde_urlencoded" 1708 | version = "0.7.1" 1709 | source = "registry+https://github.com/rust-lang/crates.io-index" 1710 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1711 | dependencies = [ 1712 | "form_urlencoded", 1713 | "itoa", 1714 | "ryu", 1715 | "serde", 1716 | ] 1717 | 1718 | [[package]] 1719 | name = "simba" 1720 | version = "0.7.3" 1721 | source = "registry+https://github.com/rust-lang/crates.io-index" 1722 | checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176" 1723 | dependencies = [ 1724 | "approx", 1725 | "num-complex", 1726 | "num-traits", 1727 | "paste", 1728 | "wide", 1729 | ] 1730 | 1731 | [[package]] 1732 | name = "simd-adler32" 1733 | version = "0.3.5" 1734 | source = "registry+https://github.com/rust-lang/crates.io-index" 1735 | checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" 1736 | 1737 | [[package]] 1738 | name = "slab" 1739 | version = "0.4.8" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 1742 | dependencies = [ 1743 | "autocfg", 1744 | ] 1745 | 1746 | [[package]] 1747 | name = "smallvec" 1748 | version = "1.10.0" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1751 | 1752 | [[package]] 1753 | name = "socket2" 1754 | version = "0.4.9" 1755 | source = "registry+https://github.com/rust-lang/crates.io-index" 1756 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1757 | dependencies = [ 1758 | "libc", 1759 | "winapi", 1760 | ] 1761 | 1762 | [[package]] 1763 | name = "spin" 1764 | version = "0.5.2" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1767 | 1768 | [[package]] 1769 | name = "spin" 1770 | version = "0.9.8" 1771 | source = "registry+https://github.com/rust-lang/crates.io-index" 1772 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1773 | dependencies = [ 1774 | "lock_api", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "syn" 1779 | version = "1.0.109" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1782 | dependencies = [ 1783 | "proc-macro2", 1784 | "quote", 1785 | "unicode-ident", 1786 | ] 1787 | 1788 | [[package]] 1789 | name = "syn" 1790 | version = "2.0.18" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" 1793 | dependencies = [ 1794 | "proc-macro2", 1795 | "quote", 1796 | "unicode-ident", 1797 | ] 1798 | 1799 | [[package]] 1800 | name = "tar" 1801 | version = "0.4.38" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" 1804 | dependencies = [ 1805 | "filetime", 1806 | "libc", 1807 | "xattr", 1808 | ] 1809 | 1810 | [[package]] 1811 | name = "tempfile" 1812 | version = "3.6.0" 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" 1814 | checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" 1815 | dependencies = [ 1816 | "autocfg", 1817 | "cfg-if", 1818 | "fastrand", 1819 | "redox_syscall 0.3.5", 1820 | "rustix", 1821 | "windows-sys 0.48.0", 1822 | ] 1823 | 1824 | [[package]] 1825 | name = "textwrap" 1826 | version = "0.16.0" 1827 | source = "registry+https://github.com/rust-lang/crates.io-index" 1828 | checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" 1829 | 1830 | [[package]] 1831 | name = "thiserror" 1832 | version = "1.0.40" 1833 | source = "registry+https://github.com/rust-lang/crates.io-index" 1834 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 1835 | dependencies = [ 1836 | "thiserror-impl", 1837 | ] 1838 | 1839 | [[package]] 1840 | name = "thiserror-impl" 1841 | version = "1.0.40" 1842 | source = "registry+https://github.com/rust-lang/crates.io-index" 1843 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 1844 | dependencies = [ 1845 | "proc-macro2", 1846 | "quote", 1847 | "syn 2.0.18", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "tiff" 1852 | version = "0.8.1" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" 1855 | dependencies = [ 1856 | "flate2", 1857 | "jpeg-decoder", 1858 | "weezl", 1859 | ] 1860 | 1861 | [[package]] 1862 | name = "tinytemplate" 1863 | version = "1.2.1" 1864 | source = "registry+https://github.com/rust-lang/crates.io-index" 1865 | checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" 1866 | dependencies = [ 1867 | "serde", 1868 | "serde_json", 1869 | ] 1870 | 1871 | [[package]] 1872 | name = "tinyvec" 1873 | version = "1.6.0" 1874 | source = "registry+https://github.com/rust-lang/crates.io-index" 1875 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1876 | dependencies = [ 1877 | "tinyvec_macros", 1878 | ] 1879 | 1880 | [[package]] 1881 | name = "tinyvec_macros" 1882 | version = "0.1.1" 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" 1884 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1885 | 1886 | [[package]] 1887 | name = "tokio" 1888 | version = "1.28.2" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" 1891 | dependencies = [ 1892 | "autocfg", 1893 | "bytes", 1894 | "libc", 1895 | "mio", 1896 | "num_cpus", 1897 | "pin-project-lite", 1898 | "socket2", 1899 | "windows-sys 0.48.0", 1900 | ] 1901 | 1902 | [[package]] 1903 | name = "tokio-native-tls" 1904 | version = "0.3.1" 1905 | source = "registry+https://github.com/rust-lang/crates.io-index" 1906 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1907 | dependencies = [ 1908 | "native-tls", 1909 | "tokio", 1910 | ] 1911 | 1912 | [[package]] 1913 | name = "tokio-util" 1914 | version = "0.7.8" 1915 | source = "registry+https://github.com/rust-lang/crates.io-index" 1916 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1917 | dependencies = [ 1918 | "bytes", 1919 | "futures-core", 1920 | "futures-sink", 1921 | "pin-project-lite", 1922 | "tokio", 1923 | "tracing", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "tower-service" 1928 | version = "0.3.2" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1931 | 1932 | [[package]] 1933 | name = "tracing" 1934 | version = "0.1.37" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1937 | dependencies = [ 1938 | "cfg-if", 1939 | "pin-project-lite", 1940 | "tracing-attributes", 1941 | "tracing-core", 1942 | ] 1943 | 1944 | [[package]] 1945 | name = "tracing-attributes" 1946 | version = "0.1.25" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "8803eee176538f94ae9a14b55b2804eb7e1441f8210b1c31290b3bccdccff73b" 1949 | dependencies = [ 1950 | "proc-macro2", 1951 | "quote", 1952 | "syn 2.0.18", 1953 | ] 1954 | 1955 | [[package]] 1956 | name = "tracing-core" 1957 | version = "0.1.31" 1958 | source = "registry+https://github.com/rust-lang/crates.io-index" 1959 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1960 | dependencies = [ 1961 | "once_cell", 1962 | ] 1963 | 1964 | [[package]] 1965 | name = "try-lock" 1966 | version = "0.2.4" 1967 | source = "registry+https://github.com/rust-lang/crates.io-index" 1968 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1969 | 1970 | [[package]] 1971 | name = "ttf-parser" 1972 | version = "0.15.2" 1973 | source = "registry+https://github.com/rust-lang/crates.io-index" 1974 | checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" 1975 | 1976 | [[package]] 1977 | name = "typenum" 1978 | version = "1.16.0" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1981 | 1982 | [[package]] 1983 | name = "unicode-bidi" 1984 | version = "0.3.13" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1987 | 1988 | [[package]] 1989 | name = "unicode-ident" 1990 | version = "1.0.9" 1991 | source = "registry+https://github.com/rust-lang/crates.io-index" 1992 | checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" 1993 | 1994 | [[package]] 1995 | name = "unicode-normalization" 1996 | version = "0.1.22" 1997 | source = "registry+https://github.com/rust-lang/crates.io-index" 1998 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1999 | dependencies = [ 2000 | "tinyvec", 2001 | ] 2002 | 2003 | [[package]] 2004 | name = "unicode-width" 2005 | version = "0.1.10" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 2008 | 2009 | [[package]] 2010 | name = "untrusted" 2011 | version = "0.7.1" 2012 | source = "registry+https://github.com/rust-lang/crates.io-index" 2013 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 2014 | 2015 | [[package]] 2016 | name = "ureq" 2017 | version = "2.7.1" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" 2020 | dependencies = [ 2021 | "base64", 2022 | "log", 2023 | "once_cell", 2024 | "rustls", 2025 | "rustls-webpki", 2026 | "url", 2027 | "webpki-roots", 2028 | ] 2029 | 2030 | [[package]] 2031 | name = "url" 2032 | version = "2.4.0" 2033 | source = "registry+https://github.com/rust-lang/crates.io-index" 2034 | checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" 2035 | dependencies = [ 2036 | "form_urlencoded", 2037 | "idna", 2038 | "percent-encoding", 2039 | ] 2040 | 2041 | [[package]] 2042 | name = "vcpkg" 2043 | version = "0.2.15" 2044 | source = "registry+https://github.com/rust-lang/crates.io-index" 2045 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2046 | 2047 | [[package]] 2048 | name = "vswhom" 2049 | version = "0.1.0" 2050 | source = "registry+https://github.com/rust-lang/crates.io-index" 2051 | checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" 2052 | dependencies = [ 2053 | "libc", 2054 | "vswhom-sys", 2055 | ] 2056 | 2057 | [[package]] 2058 | name = "vswhom-sys" 2059 | version = "0.1.2" 2060 | source = "registry+https://github.com/rust-lang/crates.io-index" 2061 | checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" 2062 | dependencies = [ 2063 | "cc", 2064 | "libc", 2065 | ] 2066 | 2067 | [[package]] 2068 | name = "walkdir" 2069 | version = "2.3.3" 2070 | source = "registry+https://github.com/rust-lang/crates.io-index" 2071 | checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" 2072 | dependencies = [ 2073 | "same-file", 2074 | "winapi-util", 2075 | ] 2076 | 2077 | [[package]] 2078 | name = "want" 2079 | version = "0.3.1" 2080 | source = "registry+https://github.com/rust-lang/crates.io-index" 2081 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2082 | dependencies = [ 2083 | "try-lock", 2084 | ] 2085 | 2086 | [[package]] 2087 | name = "wasi" 2088 | version = "0.9.0+wasi-snapshot-preview1" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2091 | 2092 | [[package]] 2093 | name = "wasi" 2094 | version = "0.11.0+wasi-snapshot-preview1" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2097 | 2098 | [[package]] 2099 | name = "wasm-bindgen" 2100 | version = "0.2.87" 2101 | source = "registry+https://github.com/rust-lang/crates.io-index" 2102 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 2103 | dependencies = [ 2104 | "cfg-if", 2105 | "wasm-bindgen-macro", 2106 | ] 2107 | 2108 | [[package]] 2109 | name = "wasm-bindgen-backend" 2110 | version = "0.2.87" 2111 | source = "registry+https://github.com/rust-lang/crates.io-index" 2112 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 2113 | dependencies = [ 2114 | "bumpalo", 2115 | "log", 2116 | "once_cell", 2117 | "proc-macro2", 2118 | "quote", 2119 | "syn 2.0.18", 2120 | "wasm-bindgen-shared", 2121 | ] 2122 | 2123 | [[package]] 2124 | name = "wasm-bindgen-futures" 2125 | version = "0.4.37" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" 2128 | dependencies = [ 2129 | "cfg-if", 2130 | "js-sys", 2131 | "wasm-bindgen", 2132 | "web-sys", 2133 | ] 2134 | 2135 | [[package]] 2136 | name = "wasm-bindgen-macro" 2137 | version = "0.2.87" 2138 | source = "registry+https://github.com/rust-lang/crates.io-index" 2139 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 2140 | dependencies = [ 2141 | "quote", 2142 | "wasm-bindgen-macro-support", 2143 | ] 2144 | 2145 | [[package]] 2146 | name = "wasm-bindgen-macro-support" 2147 | version = "0.2.87" 2148 | source = "registry+https://github.com/rust-lang/crates.io-index" 2149 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 2150 | dependencies = [ 2151 | "proc-macro2", 2152 | "quote", 2153 | "syn 2.0.18", 2154 | "wasm-bindgen-backend", 2155 | "wasm-bindgen-shared", 2156 | ] 2157 | 2158 | [[package]] 2159 | name = "wasm-bindgen-shared" 2160 | version = "0.2.87" 2161 | source = "registry+https://github.com/rust-lang/crates.io-index" 2162 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 2163 | 2164 | [[package]] 2165 | name = "web-sys" 2166 | version = "0.3.64" 2167 | source = "registry+https://github.com/rust-lang/crates.io-index" 2168 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 2169 | dependencies = [ 2170 | "js-sys", 2171 | "wasm-bindgen", 2172 | ] 2173 | 2174 | [[package]] 2175 | name = "webpki-roots" 2176 | version = "0.23.1" 2177 | source = "registry+https://github.com/rust-lang/crates.io-index" 2178 | checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" 2179 | dependencies = [ 2180 | "rustls-webpki", 2181 | ] 2182 | 2183 | [[package]] 2184 | name = "weezl" 2185 | version = "0.1.7" 2186 | source = "registry+https://github.com/rust-lang/crates.io-index" 2187 | checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" 2188 | 2189 | [[package]] 2190 | name = "wide" 2191 | version = "0.7.10" 2192 | source = "registry+https://github.com/rust-lang/crates.io-index" 2193 | checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" 2194 | dependencies = [ 2195 | "bytemuck", 2196 | "safe_arch", 2197 | ] 2198 | 2199 | [[package]] 2200 | name = "winapi" 2201 | version = "0.3.9" 2202 | source = "registry+https://github.com/rust-lang/crates.io-index" 2203 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2204 | dependencies = [ 2205 | "winapi-i686-pc-windows-gnu", 2206 | "winapi-x86_64-pc-windows-gnu", 2207 | ] 2208 | 2209 | [[package]] 2210 | name = "winapi-i686-pc-windows-gnu" 2211 | version = "0.4.0" 2212 | source = "registry+https://github.com/rust-lang/crates.io-index" 2213 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2214 | 2215 | [[package]] 2216 | name = "winapi-util" 2217 | version = "0.1.5" 2218 | source = "registry+https://github.com/rust-lang/crates.io-index" 2219 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2220 | dependencies = [ 2221 | "winapi", 2222 | ] 2223 | 2224 | [[package]] 2225 | name = "winapi-x86_64-pc-windows-gnu" 2226 | version = "0.4.0" 2227 | source = "registry+https://github.com/rust-lang/crates.io-index" 2228 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2229 | 2230 | [[package]] 2231 | name = "windows-sys" 2232 | version = "0.42.0" 2233 | source = "registry+https://github.com/rust-lang/crates.io-index" 2234 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 2235 | dependencies = [ 2236 | "windows_aarch64_gnullvm 0.42.2", 2237 | "windows_aarch64_msvc 0.42.2", 2238 | "windows_i686_gnu 0.42.2", 2239 | "windows_i686_msvc 0.42.2", 2240 | "windows_x86_64_gnu 0.42.2", 2241 | "windows_x86_64_gnullvm 0.42.2", 2242 | "windows_x86_64_msvc 0.42.2", 2243 | ] 2244 | 2245 | [[package]] 2246 | name = "windows-sys" 2247 | version = "0.45.0" 2248 | source = "registry+https://github.com/rust-lang/crates.io-index" 2249 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 2250 | dependencies = [ 2251 | "windows-targets 0.42.2", 2252 | ] 2253 | 2254 | [[package]] 2255 | name = "windows-sys" 2256 | version = "0.48.0" 2257 | source = "registry+https://github.com/rust-lang/crates.io-index" 2258 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2259 | dependencies = [ 2260 | "windows-targets 0.48.0", 2261 | ] 2262 | 2263 | [[package]] 2264 | name = "windows-targets" 2265 | version = "0.42.2" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 2268 | dependencies = [ 2269 | "windows_aarch64_gnullvm 0.42.2", 2270 | "windows_aarch64_msvc 0.42.2", 2271 | "windows_i686_gnu 0.42.2", 2272 | "windows_i686_msvc 0.42.2", 2273 | "windows_x86_64_gnu 0.42.2", 2274 | "windows_x86_64_gnullvm 0.42.2", 2275 | "windows_x86_64_msvc 0.42.2", 2276 | ] 2277 | 2278 | [[package]] 2279 | name = "windows-targets" 2280 | version = "0.48.0" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 2283 | dependencies = [ 2284 | "windows_aarch64_gnullvm 0.48.0", 2285 | "windows_aarch64_msvc 0.48.0", 2286 | "windows_i686_gnu 0.48.0", 2287 | "windows_i686_msvc 0.48.0", 2288 | "windows_x86_64_gnu 0.48.0", 2289 | "windows_x86_64_gnullvm 0.48.0", 2290 | "windows_x86_64_msvc 0.48.0", 2291 | ] 2292 | 2293 | [[package]] 2294 | name = "windows_aarch64_gnullvm" 2295 | version = "0.42.2" 2296 | source = "registry+https://github.com/rust-lang/crates.io-index" 2297 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 2298 | 2299 | [[package]] 2300 | name = "windows_aarch64_gnullvm" 2301 | version = "0.48.0" 2302 | source = "registry+https://github.com/rust-lang/crates.io-index" 2303 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 2304 | 2305 | [[package]] 2306 | name = "windows_aarch64_msvc" 2307 | version = "0.42.2" 2308 | source = "registry+https://github.com/rust-lang/crates.io-index" 2309 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 2310 | 2311 | [[package]] 2312 | name = "windows_aarch64_msvc" 2313 | version = "0.48.0" 2314 | source = "registry+https://github.com/rust-lang/crates.io-index" 2315 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 2316 | 2317 | [[package]] 2318 | name = "windows_i686_gnu" 2319 | version = "0.42.2" 2320 | source = "registry+https://github.com/rust-lang/crates.io-index" 2321 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 2322 | 2323 | [[package]] 2324 | name = "windows_i686_gnu" 2325 | version = "0.48.0" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 2328 | 2329 | [[package]] 2330 | name = "windows_i686_msvc" 2331 | version = "0.42.2" 2332 | source = "registry+https://github.com/rust-lang/crates.io-index" 2333 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 2334 | 2335 | [[package]] 2336 | name = "windows_i686_msvc" 2337 | version = "0.48.0" 2338 | source = "registry+https://github.com/rust-lang/crates.io-index" 2339 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 2340 | 2341 | [[package]] 2342 | name = "windows_x86_64_gnu" 2343 | version = "0.42.2" 2344 | source = "registry+https://github.com/rust-lang/crates.io-index" 2345 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 2346 | 2347 | [[package]] 2348 | name = "windows_x86_64_gnu" 2349 | version = "0.48.0" 2350 | source = "registry+https://github.com/rust-lang/crates.io-index" 2351 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 2352 | 2353 | [[package]] 2354 | name = "windows_x86_64_gnullvm" 2355 | version = "0.42.2" 2356 | source = "registry+https://github.com/rust-lang/crates.io-index" 2357 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 2358 | 2359 | [[package]] 2360 | name = "windows_x86_64_gnullvm" 2361 | version = "0.48.0" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 2364 | 2365 | [[package]] 2366 | name = "windows_x86_64_msvc" 2367 | version = "0.42.2" 2368 | source = "registry+https://github.com/rust-lang/crates.io-index" 2369 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 2370 | 2371 | [[package]] 2372 | name = "windows_x86_64_msvc" 2373 | version = "0.48.0" 2374 | source = "registry+https://github.com/rust-lang/crates.io-index" 2375 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 2376 | 2377 | [[package]] 2378 | name = "winreg" 2379 | version = "0.10.1" 2380 | source = "registry+https://github.com/rust-lang/crates.io-index" 2381 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 2382 | dependencies = [ 2383 | "winapi", 2384 | ] 2385 | 2386 | [[package]] 2387 | name = "xattr" 2388 | version = "0.2.3" 2389 | source = "registry+https://github.com/rust-lang/crates.io-index" 2390 | checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" 2391 | dependencies = [ 2392 | "libc", 2393 | ] 2394 | 2395 | [[package]] 2396 | name = "zip" 2397 | version = "0.6.6" 2398 | source = "registry+https://github.com/rust-lang/crates.io-index" 2399 | checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" 2400 | dependencies = [ 2401 | "byteorder", 2402 | "crc32fast", 2403 | "crossbeam-utils", 2404 | "flate2", 2405 | ] 2406 | 2407 | [[package]] 2408 | name = "zune-inflate" 2409 | version = "0.2.54" 2410 | source = "registry+https://github.com/rust-lang/crates.io-index" 2411 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 2412 | dependencies = [ 2413 | "simd-adler32", 2414 | ] 2415 | --------------------------------------------------------------------------------