Compare commits
13 Commits
visions-us
...
main
Author | SHA1 | Date | |
---|---|---|---|
a2cdaef689 | |||
49c7a37d28 | |||
aa155dc090 | |||
da5144caea | |||
f9e4dcd68a | |||
35abcfcf28 | |||
cc4f8c1515 | |||
d5b4d051a5 | |||
81143f0b9c | |||
f59c3544b4 | |||
208083d39e | |||
08462388ea | |||
dc8cb834e0 |
1744
Cargo.lock
generated
1744
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# "authdb",
|
||||
"authdb",
|
||||
# "bike-lights/bike",
|
||||
"bike-lights/core",
|
||||
"bike-lights/simulator",
|
||||
@ -14,7 +14,7 @@ members = [
|
||||
"cyberpunk-splash",
|
||||
"dashboard",
|
||||
"emseries",
|
||||
# "file-service",
|
||||
"file-service",
|
||||
"fitnesstrax/core",
|
||||
"fitnesstrax/app",
|
||||
"fluent-ergonomics",
|
||||
@ -22,7 +22,6 @@ members = [
|
||||
"gm-control-panel",
|
||||
"hex-grid",
|
||||
"icon-test",
|
||||
"ifc",
|
||||
"memorycache",
|
||||
"nom-training",
|
||||
"otg/core",
|
||||
|
16
Taskfile.yml
Normal file
16
Taskfile.yml
Normal file
@ -0,0 +1,16 @@
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- cargo build --release
|
||||
|
||||
update:
|
||||
cmds:
|
||||
- task build
|
||||
- crate2nix generate
|
||||
- nix build
|
||||
|
||||
lint:
|
||||
cmds:
|
||||
- cargo watch -x clippy
|
@ -38,7 +38,7 @@ pub struct Instant(pub U128F0);
|
||||
|
||||
impl Default for Instant {
|
||||
fn default() -> Self {
|
||||
Self(U128F0::from(0 as u8))
|
||||
Self(U128F0::from(0_u8))
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ impl Blinker {
|
||||
direction: BlinkerDirection,
|
||||
time: Instant,
|
||||
) -> Self {
|
||||
let mut ending_dashboard = OFF_DASHBOARD.clone();
|
||||
let mut ending_dashboard = OFF_DASHBOARD;
|
||||
|
||||
match direction {
|
||||
BlinkerDirection::Left => {
|
||||
@ -213,7 +213,7 @@ impl Blinker {
|
||||
}
|
||||
}
|
||||
|
||||
let mut ending_body = OFF_BODY.clone();
|
||||
let mut ending_body = OFF_BODY;
|
||||
match direction {
|
||||
BlinkerDirection::Left => {
|
||||
for i in 0..30 {
|
||||
@ -233,26 +233,26 @@ impl Blinker {
|
||||
|
||||
Blinker {
|
||||
transition: Fade::new(
|
||||
starting_dashboard.clone(),
|
||||
starting_body.clone(),
|
||||
ending_dashboard.clone(),
|
||||
ending_body.clone(),
|
||||
starting_dashboard,
|
||||
starting_body,
|
||||
ending_dashboard,
|
||||
ending_body,
|
||||
BLINKER_FRAMES,
|
||||
time,
|
||||
),
|
||||
fade_in: Fade::new(
|
||||
OFF_DASHBOARD.clone(),
|
||||
OFF_BODY.clone(),
|
||||
ending_dashboard.clone(),
|
||||
ending_body.clone(),
|
||||
OFF_DASHBOARD,
|
||||
OFF_BODY,
|
||||
ending_dashboard,
|
||||
ending_body,
|
||||
BLINKER_FRAMES,
|
||||
time,
|
||||
),
|
||||
fade_out: Fade::new(
|
||||
ending_dashboard.clone(),
|
||||
ending_body.clone(),
|
||||
OFF_DASHBOARD.clone(),
|
||||
OFF_BODY.clone(),
|
||||
ending_dashboard,
|
||||
ending_body,
|
||||
OFF_DASHBOARD,
|
||||
OFF_BODY,
|
||||
BLINKER_FRAMES,
|
||||
time,
|
||||
),
|
||||
@ -375,7 +375,7 @@ impl App {
|
||||
pattern.dashboard(),
|
||||
pattern.body(),
|
||||
DEFAULT_FRAMES,
|
||||
Instant((0 as u32).into()),
|
||||
Instant(0_u32.into()),
|
||||
)),
|
||||
dashboard_lights: OFF_DASHBOARD,
|
||||
lights: OFF_BODY,
|
||||
@ -386,8 +386,8 @@ impl App {
|
||||
match self.state {
|
||||
State::Pattern(ref pattern) => {
|
||||
self.current_animation = Box::new(Fade::new(
|
||||
self.dashboard_lights.clone(),
|
||||
self.lights.clone(),
|
||||
self.dashboard_lights,
|
||||
self.lights,
|
||||
pattern.dashboard(),
|
||||
pattern.body(),
|
||||
DEFAULT_FRAMES,
|
||||
@ -396,8 +396,8 @@ impl App {
|
||||
}
|
||||
State::Brake => {
|
||||
self.current_animation = Box::new(Fade::new(
|
||||
self.dashboard_lights.clone(),
|
||||
self.lights.clone(),
|
||||
self.dashboard_lights,
|
||||
self.lights,
|
||||
BRAKES_DASHBOARD,
|
||||
BRAKES_BODY,
|
||||
BRAKES_FRAMES,
|
||||
@ -406,16 +406,16 @@ impl App {
|
||||
}
|
||||
State::LeftBlinker => {
|
||||
self.current_animation = Box::new(Blinker::new(
|
||||
self.dashboard_lights.clone(),
|
||||
self.lights.clone(),
|
||||
self.dashboard_lights,
|
||||
self.lights,
|
||||
BlinkerDirection::Left,
|
||||
time,
|
||||
));
|
||||
}
|
||||
State::RightBlinker => {
|
||||
self.current_animation = Box::new(Blinker::new(
|
||||
self.dashboard_lights.clone(),
|
||||
self.lights.clone(),
|
||||
self.dashboard_lights,
|
||||
self.lights,
|
||||
BlinkerDirection::Right,
|
||||
time,
|
||||
));
|
||||
@ -441,19 +441,13 @@ impl App {
|
||||
State::LeftBlinker => self.state = State::Pattern(self.home_pattern),
|
||||
_ => self.state = State::LeftBlinker,
|
||||
},
|
||||
Event::NextPattern => match self.state {
|
||||
State::Pattern(ref pattern) => {
|
||||
Event::NextPattern => if let State::Pattern(ref pattern) = self.state {
|
||||
self.home_pattern = pattern.next();
|
||||
self.state = State::Pattern(self.home_pattern);
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Event::PreviousPattern => match self.state {
|
||||
State::Pattern(ref pattern) => {
|
||||
Event::PreviousPattern => if let State::Pattern(ref pattern) = self.state {
|
||||
self.home_pattern = pattern.previous();
|
||||
self.state = State::Pattern(self.home_pattern);
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Event::RightBlinker => match self.state {
|
||||
State::Brake => self.state = State::BrakeRightBlinker,
|
||||
@ -465,17 +459,14 @@ impl App {
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, time: Instant) {
|
||||
match self.ui.check_event(time) {
|
||||
Some(event) => {
|
||||
if let Some(event) = self.ui.check_event(time) {
|
||||
self.update_state(event);
|
||||
self.update_animation(time);
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
|
||||
let (dashboard, lights) = self.current_animation.tick(time);
|
||||
self.dashboard_lights = dashboard.clone();
|
||||
self.lights = lights.clone();
|
||||
self.dashboard_lights = dashboard;
|
||||
self.lights = lights;
|
||||
self.ui.update_lights(dashboard, lights);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
adw = { version = "0.5", package = "libadwaita", features = [ "v1_2" ] }
|
||||
async-std = "1.13.0"
|
||||
cairo-rs = { version = "0.18" }
|
||||
fixed = { version = "1" }
|
||||
gio = { version = "0.18" }
|
||||
|
@ -1,6 +1,7 @@
|
||||
use adw::prelude::*;
|
||||
use async_std::channel::Sender;
|
||||
use fixed::types::{I8F8, U128F0};
|
||||
use glib::{Object, Sender};
|
||||
use glib::Object;
|
||||
use gtk::subclass::prelude::*;
|
||||
use lights_core::{
|
||||
App, BodyPattern, DashboardPattern, Event, Instant, FPS, OFF_BODY, OFF_DASHBOARD, RGB, UI,
|
||||
@ -45,6 +46,12 @@ glib::wrapper! {
|
||||
pub struct DashboardLights(ObjectSubclass<DashboardLightsPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
||||
}
|
||||
|
||||
impl Default for DashboardLights {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DashboardLights {
|
||||
pub fn new() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
@ -103,6 +110,12 @@ glib::wrapper! {
|
||||
pub struct BikeLights(ObjectSubclass<BikeLightsPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
||||
}
|
||||
|
||||
impl Default for BikeLights {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl BikeLights {
|
||||
pub fn new() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
@ -161,12 +174,15 @@ impl UI for GTKUI {
|
||||
}
|
||||
|
||||
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: BodyPattern) {
|
||||
self.tx
|
||||
let tx = self.tx.clone();
|
||||
glib::spawn_future(async move {
|
||||
let _ = tx
|
||||
.send(Update {
|
||||
dashboard: dashboard_lights,
|
||||
lights,
|
||||
})
|
||||
.unwrap();
|
||||
.await;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,8 +192,7 @@ fn main() {
|
||||
.build();
|
||||
|
||||
adw_app.connect_activate(move |adw_app| {
|
||||
let (update_tx, update_rx) =
|
||||
gtk::glib::MainContext::channel::<Update>(gtk::glib::Priority::DEFAULT);
|
||||
let (update_tx, update_rx) = async_std::channel::unbounded();
|
||||
let (event_tx, event_rx) = std::sync::mpsc::channel();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
@ -269,6 +284,17 @@ fn main() {
|
||||
layout.append(&dashboard_lights);
|
||||
layout.append(&bike_lights);
|
||||
|
||||
glib::spawn_future_local({
|
||||
let dashboard_lights = dashboard_lights.clone();
|
||||
let bike_lights = bike_lights.clone();
|
||||
async move {
|
||||
while let Ok(Update { dashboard, lights }) = update_rx.recv().await {
|
||||
dashboard_lights.set_lights(dashboard);
|
||||
bike_lights.set_lights(lights);
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
update_rx.attach(None, {
|
||||
let dashboard_lights = dashboard_lights.clone();
|
||||
let bike_lights = bike_lights.clone();
|
||||
@ -278,6 +304,7 @@ fn main() {
|
||||
glib::ControlFlow::Continue
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
window.set_content(Some(&layout));
|
||||
window.present();
|
||||
|
@ -40,6 +40,12 @@ macro_rules! define_config {
|
||||
values: std::collections::HashMap<ConfigName, ConfigOption>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -145,7 +145,7 @@ mod tests {
|
||||
|
||||
let coord2 = &lst1[idx];
|
||||
assert!(coord2.is_adjacent(&coord1));
|
||||
assert!(coord1.is_adjacent(&coord2));
|
||||
assert!(coord1.is_adjacent(coord2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -166,10 +166,10 @@ mod tests {
|
||||
let hexaddr = AxialAddr::new(q, r);
|
||||
let en_distancaj_hexaddr: Vec<AxialAddr> = hexaddr.addresses(distance).collect();
|
||||
|
||||
let expected_cnt = ((0..distance+1).map(|v| v * 6).fold(1, |acc, val| acc + val)) as usize;
|
||||
let expected_cnt = (0..distance+1).map(|v| v * 6).fold(1, |acc, val| acc + val);
|
||||
assert_eq!(en_distancaj_hexaddr.len(), expected_cnt);
|
||||
for c in en_distancaj_hexaddr {
|
||||
assert!(c.distance(&hexaddr) <= distance as usize);
|
||||
assert!(c.distance(&hexaddr) <= distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,112 +5,125 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#adler@1.0.2": "1zim79cvzd5yrkzl3nyfx0avijwgk9fqv3yrscdy1cc79ih02qpj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#ahash@0.8.11": "04chdfkls5xmhp1d48gnjsmglbqibizs3bpbj6rsj604m10si7g8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.3": "05mrpkvdgp5d20y2p989f187ry9diliijgwrs254fs9s1m1x6q4f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#allocator-api2@0.2.18": "0kr6lfnxvnj164j1x38g97qjlhb7akppqzvgfs0697140ixbav2w",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#allocator-api2@0.2.21": "08zrzs022xwndihvzdn78yqarv2b9696y67i6h78nla3ww87jgb8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#android-tzdata@0.1.1": "1w7ynjxrfs97xg3qlcdns4kgfpwcdv824g611fq32cag4cdr96g9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#android_system_properties@0.1.5": "04b3wrz12837j7mdczqd95b732gw5q7q66cv4yn4646lvccp57l1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#annotate-snippets@0.9.2": "07p8r6jzb7nqydq0kr5pllckqcdxlyld2g275v425axnzffpxbyc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.15": "09nm4qj34kiwgzczdvj14x7hgsb235g4sqsay3xsz7zqn4d5rqb4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.5": "1jy12rvgbldflnb2x7mcww9dcffw1mx22nyv6p3n7d62h0gdwizb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.1": "0aj22iy4pzk6mz745sfrm1ym14r0y892jhcrbs8nkj7nqx9gqdkd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-wincon@3.0.4": "1y2pkvsrdxbcwircahb4wimans2pzmwwxad7ikdhj5lpdqdlxxsv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.8": "1cfmkza63xpn1kkz844mgjwm9miaiz4jkyczmwxzivcsypk1vv0v",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.89": "1xh1vg89n56h6nqikcmgbpmkixjds33492klrp9m96xrbmhgizc6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.18": "16sjk4x3ns2c3ya1x28a44kh6p47c7vhk27251i015hik1lm7k4a",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.6": "1acqayy22fwzsrvr6n0lz6a4zvjjcvgr5sm941m7m0b2fr81cb9v",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.2": "036nm3lkyk43xbps1yql3583fp4hg3b1600is7mcyxs1gzrpm53r",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle-wincon@3.0.7": "0kmf0fq4c8yribdpdpylzz1zccpy84hizmcsac3wrac1f7kk8dfa",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.10": "1yai2vppmd7zlvlrp9grwll60knrmscalf8l2qpfz8b7y5lkpk2m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.95": "010vd1ki8w84dzgx6c81sc8qm9n02fxic1gkpv52zp4nwrn0kb1l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#assert-json-diff@2.0.2": "04mg3w0rh3schpla51l18362hsirl23q93aisws2irrj32wg5r27",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-channel@1.9.0": "0dbdlkzlncbibd3ij6y6jmvjd0cmdn48ydcfdpfhw09njd93r5c1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-channel@2.3.1": "0skvwxj6ysfc6d7bhczz9a2550260g62bm5gl0nmjxxyn007id49",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-executor@1.13.1": "1v6w1dbvsmw6cs4dk4lxj5dvrikc6xi479wikwaab2qy3h09mjih",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-global-executor@2.4.1": "1762s45cc134d38rrv0hyp41hv4iv6nmx59vswid2p0il8rvdc85",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-io@2.3.4": "1s679l7x6ijh8zcxqn5pqgdiyshpy4xwklv86ldm1rhfjll04js4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-io@2.4.0": "0n8h0vy53n4vdkq529scqnkzm9vcl3r73za9nj81s2nfrhiv78j3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-lock@3.4.0": "060vh45i809wcqyxzs5g69nqiqah7ydz0hpkcjys9258vqn4fvpz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-std@1.13.0": "059nbiyijwbndyrz0050skvlvzhds0dmnl0biwmxwbw055glfd66",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-task@4.7.1": "1pp3avr4ri2nbh7s6y9ws0397nkx1zymmcr14sq761ljarh3axcb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.83": "1p8q8gm4fv2fdka8hwy2w3f8df7p5inixqi7rlmbnky3wmysw73j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.85": "0mm0gwad44zs7mna4a0m1z4dhzpmydfj73w4wm23c8xpnhrli4rz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#atoi@2.0.0": "0a05h42fggmy7h0ajjv6m7z72l924i7igbx13hk9d8pyign9k3gj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2": "1h5av1lw56m0jf0fd3bchxq8a30xv0b4wv8s4zkp4s0i7mfvs18m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#auto-future@1.0.0": "0wykbakzh227vz6frx9p48zsq0wpswgmb7v3917m53m7gr2pw7iw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#autocfg@0.1.8": "0y4vw4l4izdxq1v0rrhvmlbqvalrqrmk60v1z0dqlgnlbzkl7phd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#autocfg@1.4.0": "09lz3by90d2hphbq56znag9v87gfpd9gb8nr82hll8z6x2nhprdc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#axum-core@0.4.5": "16b1496c4gm387q20hkv5ic3k5bd6xmnvk50kwsy6ymr8rhvvwh9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#axum-macros@0.4.2": "1klv77c889jm05bzayaaiinalarhvh2crc2w4nvp3l581xaj7lap",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#axum-test@16.4.1": "1p5qxacvxsagnqq30nr2wznjyhgb8svsfb925ah3d2b0s91s9qv3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#axum@0.7.9": "07z7wqczi9i8xb4460rvn39p4wjqwr32hx907crd1vwb2fy8ijpd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#az@1.2.1": "0ww9k1w3al7x5qmb7f13v3s9c2pg1pdxbs8xshqy6zyrchj4qzkv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#backtrace@0.3.74": "06pfif7nwx66qf2zaanc2fcq7m64i91ki9imw9xd3bnz5hrwp0ld",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#base64@0.21.7": "0rw52yvsk75kar9wgqfwgb414kvil1gn7mqkrhn9zf1537mpsacx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1": "1imqzgh7bxcikp5vx3shqvw9j09g9ly0xr0jma0q66i52r7jbcvj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#base64@0.9.3": "0hs62r35bgxslawyrn1vp9rmvrkkm76fqv0vqcwd048vs876r7a8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#base64ct@1.6.0": "0nvdba4jb8aikv60az40x2w1y96sjdq8z3yp09rwzmkhiwv1lg4c",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bindgen@0.69.5": "1240snlcfj663k04bjsg629g4wx6f83flgbjh5rzpgyagk3864r7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bit-set@0.5.3": "1wcm9vxi00ma4rcxkl3pzzjli6ihrpn9cfdi0c5b4cvga2mxs007",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bit-vec@0.6.3": "1ywqjnv60cdh1slhz67psnp422md6jdliji6alq0gmly2xm9p7rl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bit-set@0.8.0": "18riaa10s6n59n39vix0cr7l2dgwdhcpbcm97x1xbyfp1q47x008",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bit-vec@0.8.0": "1xxa1s2cj291r7k1whbxq840jxvmdsq9xgh7bvrxl46m80fllxjy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bit_field@0.10.2": "0qav5rpm4hqc33vmf4vc4r0mh51yjx5vmd9zhih26n9yjs3730nw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bitflags@1.3.2": "12ki6w8gn1ldq7yz9y680llwk5gmrhrzszaa17g1sbrw2r2qvwxy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bitflags@2.6.0": "1pkidwzn3hnxlsl8zizh0bncgbjnw7c41cx7bby26ncbzmiznj5h",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bitflags@2.8.0": "0dixc6168i98652jxf0z9nbyn0zcis3g6hi6qdr7z5dbhcygas4g",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4": "0w9sa2ypmrsqqvc20nhwr75wbb5cjr4kkyhpjm1z1lv2kdicfy1h",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#blocking@1.6.1": "1si99l8zp7c4zq87y35ayjgc5c9b60jb8h0k14zfcs679z2l2gvh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#build_html@2.5.0": "0p4k25yk3v0wf720wl5zcghvc9ik6l7lsh3fz86cq3g7x4nbhpi2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bumpalo@3.16.0": "0b015qb4knwanbdlp1x48pkb4pm57b8gidbhhhxr900q2wb6fabr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.18.0": "1bp2s9wn0gjsaygv21nsbfpf854vl897ll6sqpfn3naaannv1fwl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.21.0": "18wj81x9xhqcd6985r8qxmbik6szjfjfj62q3xklw8h2p3x7srgg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0": "0jzncxyf404mwqdbspihyzpkndfgda450l0893pz5xj685cg5l0z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bytes@1.7.2": "1wzs7l57iwqmrszdpr2mmqf1b1hgvpxafc30imxhnry0zfl9m3a2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bytes@1.9.0": "16ykzx24v1x4f42v2lxyvlczqhdfji3v7r4ghwckpwijzvb1hn9j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#bytesize@1.3.0": "1k3aak70iwz4s2gsjbxf0ws4xnixqbdz6p2ha96s06748fpniqx3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cairo-rs@0.18.5": "1qjfkcq3mrh3p01nnn71dy3kn99g21xx3j8xcdvzn8ll2pq6x8lc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2": "0lfsxl7ylw3phbnwmz3k58j1gnqi6kc2hdc7g3bb7f4hwnl9yp38",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cc@1.1.34": "1j9dh96lpkksmfvjfiqa5nrlswm5l6lj54m5jf7i0iik8l6lgfb7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cc@1.2.10": "0aaj2ivamhfzhgb9maasnfkh03s2mzhzpzwrkghgzbkfnv5qy80k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cexpr@0.6.0": "0rl77bwhs5p979ih4r0202cn5jrfsrbgrksp40lkfz5vk1x3ib3g",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cfg-expr@0.15.8": "00lgf717pmf5qd2qsxxzs815v6baqg38d6m5i6wlh235p14asryh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.0": "1za0vb97n4brpzpv8lsbnzmq5r8f2b0cpqqr0sy8h5bn751xxwds",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#chrono-tz-build@0.2.1": "03rmzd69cn7fp0fgkjr5042b3g54s2l941afjm3001ls7kqkjgj3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#chrono-tz@0.8.6": "0vlksnmpb6rd4h55245agnfhphnpslwnq9al3aw3is43dd3f16nm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.38": "009l8vc5p8750vn02z30mblg4pv2qhkbfizhfwmzc6vpy5nr67x2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.39": "09g8nf409lb184kl9j4s85k0kn8wzgjkp5ls9zid50b886fwqdky",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clang-sys@1.8.1": "1x1r9yqss76z8xwpdanw313ss6fniwc1r7dzb5ycjn0ph53kj0hb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap@4.5.20": "1s37v23gcxkjy4800qgnkxkpliz68vslpr5sgn1xar56hmnkfzxr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.20": "0m6w10l2f65h3ch0d53lql6p26xxrh20ffipra9ysjsfsjmq1g0r",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.18": "1ardb26bvcpg72q9myr7yir3a8c83gx7vxk1cccabsd9n73s1ija",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.2": "15zcrc2fa6ycdzaihxghf48180bnvzsivhf0fmah24bnnaf76qhl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap@4.5.26": "10v7qvn90calfbhap1c4r249i5c7fbxj09fn3szfz9pkis85xsx8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.26": "08f1mzcvi7zjhm7hvz6al4jnv70ccqhwiaq74hihlspwnl0iic4n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.24": "131ih3dm76srkbpfx7zfspp9b556zgzj31wqhl0ji2b39lcmbdsl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.4": "19nwfls5db269js5n822vkc8dw0wjq2h1wf0hgr06ld2g52d2spl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cloudabi@0.0.3": "0kxcg83jlihy0phnd2g8c2c303px3l2p3pkjz357ll6llnd5pz6x",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#color_quant@1.1.0": "12q1n427h2bbmmm1mnglr57jaz2dj9apk0plcxw7nwqiai7qjyrx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.2": "1h18ph538y8yjmbpaf8li98l0ifms2xmh3rax9666c5qfjfi3zfk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.3": "1439m3r3jy3xqck8aa13q658visn71ki76qa93cy55wkmalwlqsv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#concurrent-queue@2.5.0": "0wrr3mzq2ijdkxwndhf79k952cp4zkz35ray8hvsxl96xrx1k82c",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#const-oid@0.9.6": "1y0jnqaq7p2wvspnx7qj76m7hjcqpz73qzvr9l2p9n2s51vr6if2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#convert_case@0.6.0": "1jn1pq6fp3rri88zyw6jlhwwgf6qiyc08d6gjv0qypgkl862n67c",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cookie-factory@0.3.3": "18mka6fk3843qq3jw1fdfvzyv05kx7kcmirfbs2vg2kbw9qzm1cq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cookie@0.17.0": "096c52jg9iq4lfcps2psncswv33fc30mmnaa2sbzzcfcw71kgyvy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cookie@0.18.1": "0iy749flficrlvgr3hjmf3igr738lk81n5akzf4ym4cs6cxg7pjd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cool_asserts@2.0.3": "1v18dg7ifx41k2f82j3gsnpm1fg9wk5s4zv7sf42c7pnad72b7zf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#core-foundation-sys@0.8.7": "12w8j73lazxmr1z0h98hf3z623kl8ms7g07jch7n4p8f9nwlhdkp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#core-foundation@0.9.4": "13zvbbj07yk3b61b8fhwfzhy35535a583irf23vlcg59j7h9bqci",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.14": "1q3qd9qkw94vs7n5i0y3zz2cqgzcxvdgyb54ryngwmjhfbgrg1k0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.16": "1hy466fkhxjbb16i7na95wz8yr14d0kd578pwzj5lbkz14jh5f0n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crc-catalog@2.4.0": "1xg7sz82w3nxp1jfn425fvn1clvbzb3zgblmxsyqpys0dckp9lqr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.4.2": "1czp7vif73b8xslr3c9yxysmh9ws2r8824qda7j47ffs9pcnjxx9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crc@3.2.1": "0dnn23x68qakzc429s1y9k9y3g8fn5v9jwi63jcz151sngby9rk9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-deque@0.8.5": "03bp38ljx4wj6vvy4fbhx41q8f585zyqix6pncz1mkz93z08qgv1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-deque@0.8.6": "0l9f1saqp1gn5qy0rxvkmz4m6n7fc0b3dbm6q1r5pmgpnyvi3lcx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-epoch@0.9.18": "03j2np8llwf376m3fxqx859mgp9f83hj1w34153c7a9c7i5ar0jv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.11": "0d8y8y3z48r9javzj67v3p2yfswd278myz1j9vzc4sp7snslc0yz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.20": "100fksq5mm1n7zj242cclkw6yf7a4a8ix3lvpfkhxvdhbda9kv12",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.12": "059igaxckccj6ndmg45d5yf7cm4ps46c18m21afq3pwiiz1bnn0g",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21": "0a3aa2bmc8q35fb67432w16wvi54sfmb69rk9h5bhd18vw0c99fh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.2": "1dx9mypwd5mpfbbajm78xcrg5lirqk7934ik980mmaffg3hdm0bs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.6": "1cvby95a6xg7kxdz5ln3rl9xh66nz66w46mm3g56ri1z5x815yqv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#data-encoding@2.6.0": "1qnn68n4vragxaxlkqcb1r28d3hhj43wch67lm4rpxlw89wnjmp8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#data-encoding@2.7.0": "0vxdv88fnvnxw29gk84gj5662xlv0p5hmlxpwp7d60cckp8fwq0f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#deflate@0.8.6": "0x6iqlayg129w63999kz97m279m0jj4x4sm6gkqlvmp73y70yxvk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#der@0.7.9": "1h4vzjfa1lczxdf8avfj9qlwh1qianqlxdy1g5rn762qnvkzhnzm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#deranged@0.3.11": "1d1ibqqnr5qdrpw8rclwrf1myn3wf0dygl04idf4j2s49ah6yaxl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#diff@0.1.13": "1j0nzjxci2zqx63hdcihkp0a4dkdmzxd7my4m7zk6cjyfy34j9an",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7": "14p2n6ih29x81akj097lvz7wi9b6b9hvls0lwrv7b6xwyy0s5ncy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#dimensioned@0.7.0": "09ky8s3higkf677lmyqg30hmj66gpg7hx907s6hfvbk2a9av05r5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#dimensioned@0.8.0": "15s3j4ry943xqlac63bp81sgdk9s3yilysabzww35j9ibmnaic50",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5": "1q0alair462j21iiqwrr21iabkfnb13d6x5w95lkdg21q2xrqdlp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#dotenvy@0.15.7": "16s3n973n5aqym02692i1npb079n5mb0fwql42ikmwn8wnrrbbqs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#either@1.13.0": "1w2c1mybrd7vljyxk77y9f4w9dyjrmp3yp82mk7bcm8848fazcb0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#encoding_rs@0.8.34": "0nagpi1rjqdpvakymwmnlxzq908ncg868lml5b70n08bm82fjpdl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#encoding_rs@0.8.35": "1wv64xdrr9v37rqqdjsyb8l8wzlcbab80ryxhrszvnj59wy0y0vm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#env_logger@0.10.2": "1005v71kay9kbz1d5907l0y7vh9qn2fqsp2yfgb8bjvin6m0bm2c",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.1": "1malmx5f4lkfvqasz319lq6gb3ddg19yzf9s8cykfsgzdmyq0hsl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#errno@0.3.9": "1fi0m0493maq1jygcf1bya9cymz2pc1mqxj26bdv7yjd37v5qk2k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#errno@0.3.10": "0pgblicz1kjz9wa9m0sghkhh2zw1fhq1mxzj7ndjm746kg5m5n1k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#etcetera@0.8.0": "0hxrsn75dirbjhwgkdkh0pnpqrnq17ypyhjpjaypgax1hd91nv8k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#event-listener-strategy@0.5.2": "18f5ri227khkayhv3ndv7yl4rnasgwksl2jhwgafcxzr7324s88g",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#event-listener-strategy@0.5.3": "1ch5gf6knllyq12jkb5zdfag573dh44307q4pwwi2g37sc6lwgiw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#event-listener@2.5.3": "1q4w3pndc518crld6zsqvvpy9lkzwahp2zgza9kbzmmqh9gif1h2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#event-listener@5.3.1": "1fkm6q4hjn61wl52xyqyyxai0x9w0ngrzi0wf1qsf8vhsadvwck0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#exr@1.72.0": "195iviimjnp1mdkqrq8hjrfkr0qavpp1p8pq5qvaksa30pv96zc8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.1.1": "19nyzdq3ha4g173364y2wijmd6jlyms8qx40daqkxsnl458jmh78",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fdeflate@0.3.5": "1axmgzpgf12yl3x9ymdslqza765la17j17ljv6a4kc143a90y2fq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#event-listener@5.4.0": "1bii2gn3vaa33s0gr2zph7cagiq0ppcfxcxabs24ri9z9kgar4il",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#exr@1.73.0": "1q47yq78q9k210r6jy1wwrilxwwxqavik9l3l426rd17k7srfcgq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fallible-iterator@0.3.0": "0ja6l56yka5vn4y4pk6hn88z0bpny7a8k1919aqjzp0j1yhy9k1a",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fallible-streaming-iterator@0.1.9": "0nj6j26p71bjy8h42x6jahx1hn0ng6mc2miwpgwnp8vnwqf4jq3k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0": "1ghiahsw1jd68df895cy5h3gzwk30hndidn3b682zmshpgmrx41p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fdeflate@0.3.7": "130ga18vyxbb5idbgi07njymdaavvk6j08yh1dfarm294ssm6s0y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#field-offset@0.3.6": "0zq5sssaa2ckmcmxxbly8qgz3sxpb8g1lwv90sdh1z74qif2gqiq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fixed@1.28.0": "0nn85j5x8yzx10q49jdzia4yp6pnasnxpnwh0p9aqr7qkfwf1il5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#flate2@1.0.34": "1w1nf2ap4q1sq1v6v951011wcvljk449ap7q7jnnjf8hvjs8kdd1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#flate2@1.0.35": "0z6h0wa095wncpfngx75wyhyjnqwld7wax401gsvnzjhzgdbydn9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fluent-bundle@0.15.3": "14zl0cjn361is69pb1zry4k2zzh5nzsfv0iz05wccl00x0ga5q3z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fluent-langneg@0.13.0": "152yxplc11vmxkslvmaqak9x86xnavnhdqyhrh38ym37jscd0jic",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fluent-syntax@0.11.1": "0gd3cdvsx9ymbb8hijcsc9wyf8h1pbcbpsafg4ldba56ji30qlra",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fluent@0.16.1": "0njmdpwz52yjzyp55iik9k6vrixqiy7190d98pk0rgdy0x3n6x5v",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#flume@0.11.0": "10girdbqn77wi802pdh55lwbmymy437k7kklnvj12aaiwaflbb2m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#flume@0.11.1": "15ch0slxa8sqsi6c73a0ky6vdnh48q8cxjf7rksa3243m394s3ns",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7": "1hc2mcqha06aibcaza94vbi81j6pr9a1bbxrxjfhc91zin8yr7iz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#foldhash@0.1.4": "0vsxw2iwpgs7yy6l7pndm7b8nllaq5vdxwnmjn1qpm5kyzhzvlm0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#foreign-types-shared@0.1.1": "0jxgzd04ra4imjv8jgkmdq59kj8fsz6w4zxsbmlai34h26225c00",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#foreign-types@0.3.2": "1cgk0vyd7r45cj769jym4a6s7vwshvd0z4bqrb92q1fwibmkkwzn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.1": "0milh8x7nl4f450s3ddhg57a3flcv6yq8hlkyk6fyr3mcb128dp1",
|
||||
@ -120,7 +133,7 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31": "17vcci6mdfzx4gbk0wx64chr2f13wwwpvyf3xd5fb1gmjzcx2a0y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-intrusive@0.5.0": "0vwm08d1pli6bdaj0i7xhk3476qlx4pll6i0w03gzdnh7lh0r4qx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31": "1ikmw1yfbgvsychmsihdkwa8a1knank2d9a8dk01mbjar9w1np4y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-lite@2.3.0": "19gk4my8zhfym6gwnpdjiyv2hw8cc098skkbkhryjdaf0yspwljj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-lite@2.6.0": "0cmmgszlmkwsac9pyw5rfjakmshgx4wmzmlyn6mmjs0jav4axvgm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31": "0l1n7kqzwwmgiznn0ywdc5i24z72zvh9q1dwps54mimppi7f6bhn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31": "1xyly6naq6aqm52d5rh236snm08kw8zadydwqz8bip70s6vzlxg5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31": "124rv4n90f5xwfsm9qw6y99755y021cmi5dhzh253s920z77s3zr",
|
||||
@ -144,7 +157,7 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#glib-macros@0.18.5": "1p5cla53fcp195zp0hkqpmnn7iwmkdswhy7xh34002bw8y7j5c0b",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#glib-sys@0.18.1": "164qhsfmlzd5mhyxs8123jzbdfldwxbikfpq5cysj3lddbmy4g06",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#glib@0.18.5": "1r8fw0627nmn19bgk3xpmcfngx3wkn7mcpq5a8ma3risx3valg93",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#glob@0.3.1": "16zca52nglanv23q5qrwd5jinw3d3as5ylya6y1pbx47vkxvrynj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#glob@0.3.2": "1cm2w34b5w45fxr522h5b0fv1bxchfswcj560m3pnjbia7asvld8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#gloo-timers@0.3.0": "1519157n7xppkk6pdw5w52vy1llzn5iljkqd7q1h5609jv7l7cdv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#gobject-sys@0.18.0": "0i6fhp3m6vs3wkzyc22rk2cqj68qvgddxmpaai34l72da5xi4l08",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#graphene-rs@0.18.1": "00f4q1ra4haap5i7lazwhkdgnb49fs8adk2nm6ki6mjhl76jh8iv",
|
||||
@ -158,8 +171,9 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#h2@0.3.26": "1s7msnfv7xprzs6xzfj5sg6p8bjcdpcqcmjjbkd345cyi1x55zl1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#half@2.4.1": "123q4zzw1x4309961i69igzd1wb7pj04aaii3kwasrz3599qrl3d",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.14.5": "1wa1vy1xs3mp11bn3z9dv0jricgr6a2j0zkf1g19yz3vw4il89z5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.15.0": "1yx4xq091s7i6mw6bn77k8cp4jrpcac149xr32rg8szqsj27y20y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashlink@0.8.4": "1xy8agkyp0llbqk9fcffc1xblayrrywlyrm2a7v93x8zygm4y2g8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.15.2": "12dj0yfn59p3kh3679ac0w1fagvzf4z2zp87a13gbbqbzw0185dz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashlink@0.10.0": "1h8lzvnl9qxi3zyagivzz2p1hp6shgddfmccyf6jv7s1cdicz0kk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hashlink@0.9.1": "1byq4nyrflm5s6wdx5qwp96l1qbp2d0nljvrr5yqrsfy51qzz93b",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#headers-core@0.2.0": "0ab469xfpd411mc3dhmjhmzrhqikzyj8a17jn5bkj9zfpy0n9xp7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#headers@0.3.9": "0w62gnwh2p1lml0zqdkrx9dp438881nhz32zrzdy61qa0a9kns06",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#heck@0.4.1": "1a7mqsnycv5z4z5vnv1k34548jzmc0ajic7c1j8jsaspnhw5ql4m",
|
||||
@ -170,24 +184,41 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hex@0.4.3": "0w1a4davm1lgzpamwnba907aysmlrnygbqmfis2mqjx5m552a93z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hkdf@0.12.4": "1xxxzcarz151p1b858yn5skmhyrvn8fs4ivx5km3i1kjmnr8wpvv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hmac@0.12.1": "0pmbr069sfg76z7wsssfk5ddcqd9ncp79fyz6zcm6yn115yc6jbc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#home@0.5.9": "19grxyg35rqfd802pcc9ys1q3lafzlcjcv2pl2s5q8xpyr5kblg3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#home@0.5.11": "1kxb4k87a9sayr8jipr7nq9wpgmjk4hk4047hmf9kc24692k75aq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.2": "0kslwazg4400qnc2azkrgqqci0fppv12waicnsy5d8hncvbjjd3r",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http-body@0.4.6": "1lmyjfk6bqk6k9gkn1dxq770sb78pqbqshga241hr5p995bb5skw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1": "111ir5k2b9ihz5nr9cz7cwm7fnydca7dx4hc7vr16scfzghxrzhy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http@0.2.12": "1w81s4bcbmcj9bjp7mllm8jlz6b31wzvirz8bgpzbqkpwmbvn730",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http@1.1.0": "0n426lmcxas6h75c2cp25m933pswlrfjz10v91vc62vib2sdvf91",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#http@1.2.0": "1skglzdf98j5nzxlii540n11is0w4l80mi5sm3xrj716asps4v7i",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#httparse@1.9.5": "0ip9v8m9lvgvq1lznl31wvn0ch1v254na7lhid9p29yx9rbx6wbx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3": "1aa9rd2sac0zhjqh24c9xvir96g188zldkx0hr6dnnlx5904cfyz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#humantime@2.1.0": "1r55pfkkf5v0ji1x6izrjwdq9v6sc7bv99xj6srywcar37xmnfls",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper-tls@0.5.0": "01crgy13102iagakf6q4mb75dprzr7ps1gj0l5hxm1cvm7gks66n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.10": "1d1iwrkysjhq63pg54zk3vfby1j7zmxzm9zzyfr4lwvp0szcybfz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper@0.10.16": "0wwjh9p3mzvg3fss2lqz5r7ddcgl1fh9w6my2j69d6k0lbcm41ha",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper@0.14.30": "1jayxag79yln1nzyzx652kcy1bikgwssn6c4zrrp5v7s3pbdslm1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper@0.14.32": "1rvcb0smz8q1i0y6p7rwxr02x5sclfg2hhxf3g0774zczn0cgps1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#hyper@1.5.2": "1q7akfb443yrjzkmnnbp2vs8zi15hgbk466rr4y144v4ppabhvr5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#iana-time-zone-haiku@0.1.2": "17r6jmj31chn7xs9698r122mapq85mfnv98bb4pg6spm0si2f67k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.61": "085jjsls330yj1fnwykfzmb2f10zp6l7w4fhq81ng81574ghhpi3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_collections@1.5.0": "09j5kskirl59mvqc8kabhy7005yyy7dp88jw9f6f3gkf419a8byv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_locid@1.5.0": "0dznvd1c5b02iilqm044q4hvar0sqibq1z46prqwjzwif61vpb0k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_locid_transform@1.5.0": "0kmmi1kmj9yph6mdgkc7v3wz6995v7ly3n80vbg0zr78bp1iml81",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_locid_transform_data@1.5.0": "0vkgjixm0wzp2n3v5mw4j89ly05bg3lx96jpdggbwlpqi0rzzj7x",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@1.5.0": "0kx8qryp8ma8fw1vijbgbnf7zz9f2j4d14rw36fmjs7cl86kxkhr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@1.5.0": "05lmk0zf0q7nzjnj5kbmsigj3qgr0rwicnn5pqi9n7krmbvzpjpq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_properties@1.5.1": "1xgf584rx10xc1p7zjr78k0n4zn3g23rrg6v2ln31ingcq3h5mlk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@1.5.0": "0scms7pd5a7yxx9hfl167f5qdf44as6r3bd8myhlngnxqgxyza37",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_provider@1.5.0": "1nb8vvgw8dv2inqklvk05fs0qxzkw8xrg2n9vgid6y7gm3423m3f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#icu_provider_macros@1.5.0": "1mjs0w7fcm2lcqmbakhninzrjwqs485lkps4hz0cv3k36y9rxj0y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#idna@0.1.5": "0kl4gs5kaydn4v07c6ka33spm9qdh2np0x7iw7g5zd8z1c7rxw1q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#idna@0.5.0": "1xhjrcjqq0l5bpzvdgylvpkgk94panxgsirzhjnnqfdgc4a9nkb3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#idna@1.0.3": "0zlajvm2k3wy0ay8plr07w22hxkkmrxkffa6ah57ac6nci984vv8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.0": "0wggnkiivaj5lw0g0384ql2d7zk4ppkn3b1ry4n0ncjpr7qivjns",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#image@0.23.14": "18gn2f7xp30pf9aqka877knlq308khxqiwjvsccvzaa4f9zcpzr4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#image@0.24.9": "17gnr6ifnpzvhjf6dwbl9hki8x6bji5mwcqp0048x1jm5yfi742n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#include_dir@0.7.4": "1pfh3g45z88kwq93skng0n6g3r7zkhq9ldqs9y8rvr7i11s12gcj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#include_dir_macros@0.7.4": "0x8smnf6knd86g69p19z5lpfsaqp8w0nx14kdpkz1m8bxnkqbavw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#indent_write@2.2.0": "1hqjp80argdskrhd66g9sh542yxy8qi77j6rc69qd0l7l52rdzhc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#indexmap@2.6.0": "1nmrwn8lbs19gkvhxaawffzbvrpyrb5y3drcrr645x957kz0fybh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#indexmap@2.7.0": "07s7jmdymvd0rm4yswp0j3napx57hkjm9gs9n55lvs2g78vj5y32",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#intl-memoizer@0.5.2": "1nkvql7c7b76axv4g68di1p2m9bnxq1cbn6mlqcawf72zhhf08py",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#intl_pluralrules@7.0.2": "0wprd3h6h8nfj62d8xk71h178q7zfn3srxm787w4sawsqavsg3h7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#ipnet@2.10.1": "025p9wm94q1w2l13hbbr4cbmfygly3a2ag8g5s618l2jhq4l3hnx",
|
||||
@ -195,10 +226,10 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#is-terminal@0.4.13": "0jwgjjz33kkmnwai3nsdk1pz9vb6gkqvw1d1vq7bs3q48kinh7r6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.1": "1kwfgglh91z33kl0w5i338mfpa3zs0hidq5j4ny4rmjwrikchhvr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#itertools@0.12.1": "0s95jbb3ndj1lvfxyq5wanc0fm0r6hg6q4ngb92qlfdxvci10ads",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.11": "0nv9cqjwzr3q58qz84dcz63ggc54yhf1yqar1m858m1kfd4g3wa9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.14": "0x26kr9m062mafaxgcf2p6h2x7cmixm0zw95aipzn2hr3d5jlnnp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#jpeg-decoder@0.1.22": "1wnh0bmmswpgwhgmlizz545x8334nlbmkq8imy9k224ri3am7792",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#jpeg-decoder@0.3.1": "1c1k53svpdyfhibkmm0ir5w0v3qmcmca8xr8vnnmizwf6pdagm7m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#js-sys@0.3.70": "0yp3rz7vrn9mmqdpkds426r1p9vs6i8mkxx8ryqdfadr0s2q0s0q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#js-sys@0.3.77": "13x2qcky5l22z4xgivi59xhjjx4kxir1zg7gcj0f1ijzd4yg7yhw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#kv-log-macro@1.0.7": "0zwp4bxkkp87rl7xy2dain77z977rvcry1gmr5bssdbn541v7s0d",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#language-tags@0.2.2": "16hrjdpa827carq5x4b8zhas24d8kg4s16m6nmmn1kb7cr5qh7d9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0": "1zk6dqqni0193xg6iijh7i3i44sryglwgvx20spdvwk3r6sbrlmv",
|
||||
@ -206,19 +237,21 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#lebe@0.5.2": "1j2l6chx19qpa5gqcw434j83gyskq3g2cnffrbl3842ymlmpq203",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libadwaita-sys@0.5.3": "16n6xsy6jhbj0jbpz8yvql6c9b89a99v9vhdz5s37mg1inisl42y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libadwaita@0.5.3": "174pzn9dwsk8ikvrhx13vkh0zrpvb3rhg9yd2q5d2zjh0q6fgrrg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libc@0.2.159": "1i9xpia0hn1y8dws7all8rqng6h3lc8ymlgslnljcvm376jrf7an",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libloading@0.8.5": "194dvczq4sifwkzllfmw0qkgvilpha7m5xy90gd6i446vcpz4ya9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libm@0.2.8": "0n4hk1rs8pzw8hdfmwn96c4568s93kfxqgcqswr7sajd2diaihjf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libc@0.2.169": "02m253hs8gw0m1n8iyrsc4n15yzbqwhddi7w1l0ds7i92kdsiaxm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libloading@0.8.6": "0d2ccr88f8kv3x7va2ccjxalcjnhrci4j2kwxp7lfmbkpjs4wbzw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libm@0.2.11": "1yjgk18rk71rjbqcw9l1zaqna89p9s603k7n327nqs8dn88vwmc3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libspa-sys@0.8.0": "07yh4i5grzbxkchg6dnxlwbdw2wm5jnd7ffbhl77jr0388b9f3dz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libspa@0.8.0": "044qs48yl0llp2dmrgwxj9y1pgfy09i6fhq661zqqb9a3fwa9wv5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libsqlite3-sys@0.27.0": "05pp60ncrmyjlxxjj187808jkvpxm06w5lvvdwwvxd2qrmnj4kng",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libsqlite3-sys@0.30.1": "0jcikvgbj84xc7ikdmpc8m4y5lyqgrb9aqblphwk67kv95xgp69f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#libyml@0.0.5": "106963pwg1gc3165bdlk8bbspmk919gk10vshhqglks3z8m700ik",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.4.14": "12gsjgbhhjwywpqcrizv80vrp7p7grsz5laqq773i33wphjsxcvq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.4.15": "1aq7r2g7786hyxhv40spzf2nhag5xbw2axxc1k8z5k1dsgdm4v6j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#litemap@0.7.4": "012ili3vppd4952sh6y3qwcd0jkd0bq2qpr9h7cppc8sj11k7saf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.12": "05qvxa6g27yyva25a5ghsg85apdxkvr77yhkyhapj6r8vnf8pbq7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#log@0.3.9": "0jq23hhn5h35k7pa8r7wqnsywji6x3wn1q5q7lif5q536if8v7p1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#log@0.4.22": "093vs0wkm1rgyykk7fjbqp2lwizbixac1w52gv109p5r4jh0p9x7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#log@0.4.25": "17ydv5zhfv1zzygy458bmg3f3jx1vfziv9d74817w76yhfqgbjq4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#logger@0.4.0": "14xlxvkspcfnspjil0xi63qj5cybxn1hjmr5gq8m4v1g9k5p54bc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#matches@0.1.10": "1994402fq4viys7pjhzisj4wcw894l53g798kkm2y74laxk0jci5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#matchit@0.7.3": "156bgdmmlv4crib31qhgg49nsjk88dxkdqp80ha2pk2rk6n6ax0f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#md-5@0.10.6": "1kvq5rnpm4fzwmyv5nmnxygdhhb2369888a06gdc9pxyrzh7x7nq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#memchr@2.7.4": "18z32bhxrax0fnjikv475z7ii718hq457qwmaryixfxsl2qrmjkq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1": "12i17wh9a9plx869g7j4whf62xw68k5zd4k0k5nh6ys5mszid028",
|
||||
@ -229,9 +262,8 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#minimal-lexical@0.2.1": "16ppc5g84aijpri4jzv14rvcnslvlpphbszc7zzp6vfkddf4qdb8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.3.7": "0dblrhgbm0wa8jjl8cjp81akaj36yna92df4z1h9b26n3spal7br",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.4.4": "0jsfv00hl5rmx1nijn59sr9jmjd4rjnjhh4kdjy8d187iklih9d9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.7.4": "024wv14aa75cvik7005s5y2nfc8zfidddbd7g55g7sjgnzfl18mq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.8.0": "1wadxkg6a6z4lr7kskapj5d8pxlx7cp1ifw4daqnkzqjxych5n72",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#mio@1.0.2": "1v1cnnn44awxbcfm4zlavwgkvbyg7gp5zzjm8mqf1apkrwflvq40",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.8.3": "093r1kd1r9dyf05cbvsibgmh96pxp3qhzfvpd6f15bpggamjqh5q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#mio@1.0.3": "1gah0h4ia3avxbwym0b6bi6lr6rpysmj9zvw6zis5yq0z0xq91i8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#modifier@0.1.0": "0n3fmgli1nsskl0whrfzm1gk0rmwwl6pw1q4nb9sqqmn5h8wkxa1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#multer@2.1.0": "1hjiphaypj3phqaj5igrzcia9xfmf4rr4ddigbh8zzb96k1bvb01",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#nary_tree@0.4.3": "1iqray1a716995l9mmvz5sfqrwg9a235bvrkpcn8bcqwjnwfv1pv",
|
||||
@ -246,33 +278,32 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#num-rational@0.3.2": "01sgiwny9iflyxh2xz02sak71v2isc3x608hfdpwwzxi3j5l5b0j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19": "0h984rhdkkqd4ny9cif7y2azl3xdfb7768hb9irhpsch4q3gq787",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#num_cpus@1.16.0": "0hra6ihpnh06dvfvz9ipscys0xfqa9ca9hzp384d5m02ssvgqqa1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#object@0.36.5": "0gk8lhbs229c68lapq6w6qmnm4jkj48hrcw5ilfyswy514nhmpxf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#object@0.36.7": "11vv97djn9nc5n6w1gc6bd96d2qk2c8cg1kw5km9bsi3v4a8x532",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#once_cell@1.20.2": "0xb7rw1aqr7pa4z3b00y7786gyf8awx2gca3md73afy76dzgwq8j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl-macros@0.1.1": "173xxvfc63rr5ybwqwylsir0vq6xsj4kxiv4hmg4c3vscdmncj59",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.1.5": "1kq18qm48rvkwgcggfkqq6pm948190czqc94d6bm2sir5hq1l0gz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl-sys@0.9.103": "1mi9r5vbgqqwfa2nqlh2m0r1v5abhzjigfbi7ja0mx0xx7p8v7kz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl@0.10.66": "1hfr9ffx67j455aqrmyys3c8l65ngbqrl5qi3v3fi8vhddwg8acm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl-sys@0.9.104": "0hf712xcxmycnlc09r8d446b3mwqchsbfrjv374fp7grrc3g7as5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#openssl@0.10.68": "1xbiz2bmba2fibg70s462yk2fndp3f9vz11c7iw0ilh2y54bqx31",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0": "1iaxalcaaj59cl9n10svh4g50v8jrc1a36kd7n9yahx8j7ikfrs3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pango@0.18.3": "1r5ygq7036sv7w32kp8yxr6vgggd54iaavh3yckanmq4xg0px8kw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#parking@2.2.1": "1fnfgmzkfpjd69v4j9x737b1k8pnn054bvzcn5dm3pkgq595d3gk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.3": "09ws9g6245iiq8z975h8ycf818a66q3c6zv4b5h8skpm7hc1igzi",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.10": "1y3cf9ld9ijf7i4igwzffcn0xl16dxyn4c5bwgjck1dkgabiyh0y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#parse-zoneinfo@0.3.1": "093cs8slbd6kyfi6h12isz0mnaayf5ha8szri1xrbqj4inqhaahz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#paste@1.0.15": "02pxffpdqkapy292harq6asfjvadgp1s005fip9ljfsn9fvxgh2p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pem-rfc7468@0.7.0": "04l4852scl4zdva31c1z6jafbak0ni5pi0j38ml108zwzjdrrcw8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#percent-encoding@1.0.1": "0cgq08v1fvr6bs5fvy390cz830lq4fak8havdasdacxcw790s09i",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.1": "0gi8wgx0dcy8rnv1kywdv98lwcx67hz0a0zwpib5v2i08r88y573",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf@0.11.2": "1p03rsw66l7naqhpgr1a34r9yzi1gv9jh16g3fsk6wrwyfwdiqmd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3": "0y6hxp1d48rx2434wgi5g8j1pr8s5jja29ha2b65435fh057imhz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf@0.7.24": "066xwv4dr6056a9adlkarwp4n94kbpwngbmd47ngm3cfbyw49nmk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.11.2": "0nia6h4qfwaypvfch3pnq1nd2qj64dif4a6kai3b7rjrsf49dlz8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.11.3": "0si1n6zr93kzjs3wah04ikw8z6npsr39jw4dam8yi9czg2609y5f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.7.24": "0zjiblicfm0nrmr2xxrs6pnf6zz2394wgch6dcbd8jijkq98agmh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.2": "1c14pjyxbcpwkdgw109f7581cc5fa3fnkzdq1ikvx7mdq9jcrr28",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3": "0gc4np7s91ynrgw73s2i7iakhb4lzdv1gcyx7yhlc0n214a2701w",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.7.24": "0qi62gxk3x3whrmw5c4i71406icqk11qmpgln438p6qm7k4lqdh9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.2": "0azphb0a330ypqx3qvyffal5saqnks0xvl8rj73jlk3qxxgbkz4h",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3": "1rallyvh28jqd9i916gk5gk2igdmzlgvv5q0l3xbf3m6y8pbrsk7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.7.24": "18371fla0vsj7d6d5rlfb747xbr2in11ar9vgv5qna72bnhp2kr3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.7": "133mxf5vmvnvw4idw2y2lb5bxsza2xlyfl6psjy7mz3l12nmy3rw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.14": "00nx3f04agwjlsmd3mc5rx5haibj2v8q9b52b0kwn63wcv4nz9mx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.7": "15cvflrzsgp1zbl5gv37al2r62nl8lc37xkfwf70ql3fji7gcmxy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.8": "1yzfhf6l27nhzv7r5hfrwj2g0x7xmfhgil19fj9am4srqp06csnm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16": "16wzc7z7dfkf9bmjin22f5282783f6mdksnr0nv0j5ym5f9gyg1v",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.8": "05jr3xfy1spgmz3q19l4mmvv46vgvkvsgphamifx7x45swxcabhy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0": "117ir7vslsl2z1a7qzhws4pd01cg2d3338c47swjyvqv2n60v1wb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#piper@0.2.4": "0rn0mjjm0cwagdkay77wgmz3sqf8fqmv9d9czm79mvr2yj8c9j4n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pipewire-sys@0.8.0": "04hiy3rl8v3j2dfzp04gr7r8l5azzqqsvqdzwa7sipdij27ii7l4",
|
||||
@ -282,20 +313,21 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pkg-config@0.3.31": "1wk6yp2phl91795ia0lwkr3wl4a9xkrympvhqq8cxk4d75hwhglm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#plugin@0.2.6": "1q7nghkpvxxr168y2jnzh3w7qc9vfrby9n7ygy3xpj0bj71hsshs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#png@0.16.8": "1ipl44q3vy4kvx6j296vk7d4v8gvcg203lrkvvixwixq1j98fciw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#png@0.17.14": "1w130qw3cngzppxk1yp3ls2pbw3f0spbzhkbarbnlnm06imd9yaj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#polling@3.7.3": "04b5zdgz0m9ydbzcr3f9a55749gqbj0y89d0nz9nrv0x636r09yc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#png@0.17.16": "09kmkms9fmkbkarw0lnf0scqvjwwg3r7riddag0i3q39r0pil5c2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#polling@3.7.4": "0bs4nhwfwsvlzlhah2gbhj3aa9ynvchv2g350wapswh26a65c156",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0": "14ckj2xdpkhv3h6l5sdmb9f1d57z8hbfpdldjc2vl5givq2y77j3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.20": "017ax9ssdnpww7nrl1hvqh2lzncpv04nnsibmnw9nxjnaqlpp5bp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pretty_assertions@1.4.1": "0v8iq35ca4rw3rza5is3wjxwsf88303ivys07anc5yviybi31q9s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#pretty_env_logger@0.5.0": "076w9dnvcpx6d3mdbkqad8nwnsynb7c8haxmscyrz7g3vga28mw6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro-crate@1.3.1": "069r1k56bvgk0f58dm5swlssfcp79im230affwk6d9ck20g04k3z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro-crate@2.0.2": "092x5acqnic14cw6vacqap5kgknq3jn4c6jij9zi6j85839jc3xh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4": "0sgq6m5jfmasmwwy8x4mjygx5l7kp8s4j60bv25ckv2j1qc41gm1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error@1.0.4": "1373bhxaf0pagd8zkyd03kkx6bchzf6g0dkwrwzsnal9z47lj9fs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.89": "0vlq56v41dsj69pnk7lil7fxvbfid50jnzdn3xnr31g05mkb0fgi",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proptest@1.5.0": "13gm7mphs95cw4gbgk5qiczkmr68dvcwhp58gmiz33dq2ccm3hml",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.93": "169dw9wch753if1mgyi2nfl1il77gslvh6y2q46qplprwml6m530",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#proptest@1.6.0": "0l4y4bb8hffv7cys7d59qwqdmvmqjfzz0x9vblc08209clqfkjhl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#qoi@0.4.1": "00c0wkb112annn2wl72ixyd78mf56p4lxkhlmsggx65l3v3n8vbz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#quick-error@1.2.3": "1q6za3v78hsspisc197bg3g7rpc989qycy8ypr8ap8igv10ikl51",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.37": "1brklraw2g34bxy9y4q1nbrccn7bv36ylihv12c9vlcii55x7fdm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.38": "1k0s75w61k6ch0rs263r4j69b7vj1wadqgb9dia4ylc9mymcqk8f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rand@0.3.23": "0v679h38pjjqj5h4md7v2slsvj6686qgcn7p9fbw3h43iwnk1b34",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rand@0.4.6": "14qjfv3gggzhnma20k0sc1jf8y6pplsaq7n1j9ls5c8kf2wl0a2m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rand@0.6.5": "1jl4449jcl4wgmzld6ffwqj5gwxrp8zvx8w573g1z368qg6xlwbd",
|
||||
@ -315,34 +347,40 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rayon-core@1.12.1": "1qpwim68ai5h0j7axa8ai8z0payaawv3id0lrgkqmapx7lx8fr8l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rayon@1.10.0": "1ylgnzwgllajalr4v00y4kj22klq2jbwllm70aha232iah0sc65l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rdrand@0.4.0": "1cjq0kwx1bk7jx3kzyciiish5gqsj7620dm43dc52sr8fzmm9037",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#redox_syscall@0.5.7": "07vpgfr6a04k0x19zqr1xdlqm6fncik3zydbdi3f5g3l5k7zwvcv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.8": "18wd530ndrmygi6xnz3sp345qi0hy2kdbsa89182nwbl6br5i1rn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#redox_syscall@0.5.8": "0d48ylyd6gsamynyp257p6n2zl4dw2fhnn5z9y3nhgpri6rn5a03",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.9": "02092l8zfh3vkmk47yjc8d631zhhcd49ck2zr133prvd3z38v7l0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.5": "0p41p3hj9ww7blnbwbj9h7rwxzxg0c1hvrdycgys8rxyhqqw859b",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#regex@1.11.0": "1n5imk7yxam409ik5nagsjpwqvbg3f0g0mznd5drf549x1g0w81q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#regex@1.11.1": "148i41mzbx8bmq32hsj1q4karkzzx5m60qza6gdw4pdc9qdyyi5m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#remove_dir_all@0.5.3": "1rzqbsgkmr053bxxl04vmvsd1njyz0nxvly97aip6aa2cmb15k9s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#reqwest@0.11.27": "0qjary4hpplpgdi62d2m0xvbn6lnzckwffm0rgkm2x51023m6ryx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rsa@0.9.6": "1z0d1aavfm0v4pv8jqmqhhvvhvblla1ydzlvwykpc3mkzhj523jx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#reserve-port@2.0.1": "10x21rdb1hjzp6n5flbbw3hfd7brmirckz1q0zsf3a7s5d516f4q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rsa@0.9.7": "06amqm85raq26v6zg00fbf93lbj3kx559n2lpxc3wrvbbiy5vis7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rusqlite@0.32.1": "0vlx040bppl414pbjgbp7qr4jdxwszi9krx0m63zzf2f2whvflvp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rusqlite_migration@1.3.1": "076dm65g0sngzrb93r07va4l5zl3gjx9gq5mlsh21p7p0bl44fwj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rust-multipart-rfc7578_2@0.6.1": "0mwd3i2mk91n6diaxnkw28vyjbifhrm5ls73pcpfzz8a1i0lidq3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustc-demangle@0.1.24": "07zysaafgrkzy2rjgwqdj2a8qdpsm6zv6f5pgpk9x0lm40z9b6vi",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustc-hash@1.1.0": "1qkc5khrmv5pqi5l5ca9p5nl5hs742cagrndhbrlk3dhlrx3zm08",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustc_version@0.4.1": "14lvdsmr5si5qbqzrajgb6vfn69k0sfygrvfvr2mps26xwi3mjyg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustix@0.38.37": "04b8f99c2g36gyggf4aphw8742k2b1vls3364n2z493whj5pijwa",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustix@0.38.43": "1xjfhdnmqsbwnfmm77vyh7ldhqx0g9waqm4982404d7jdgp93257",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustls-pemfile@1.0.4": "1324n5bcns0rnw6vywr5agff3rwfvzphi7rmbyzwnv6glkhclx0w",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.19": "1m39qd65jcd1xgqzdm3017ppimiggh2446xngwp1ngr8hjbmpi7p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#rusty-fork@0.3.0": "0kxwq5c480gg6q0j3bg4zzyfh2kwmc3v2ba94jw8ncjc8mpcqgfb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.18": "17xx2s8j1lln7iackzd9p0sv546vjq71i779gphjq923vjh5pjzk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#safemem@0.3.3": "0wp0d2b2284lw11xhybhaszsczpbq1jbdklkxgifldcknmy3nw7g",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#schannel@0.1.26": "1hfip5mdwqcfnmrnkrq9d8zwy6bssmf6rfm2441nk83ghbjpn8h1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#schannel@0.1.27": "0gbbhy28v72kd5iina0z2vcdl3vz63mk5idvkzn5r52z6jmfna8z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#scoped-tls@1.0.1": "15524h04mafihcvfpgxd8f4bgc3k95aclz8grjkg9a0rxcvn9kz1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#scoped_threadpool@0.1.9": "1a26d3lk40s9mrf4imhbik7caahmw2jryhhb6vqv6fplbbgzal8x",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0": "0jcz9sd47zlsgcnm1hdw0664krxwb5gczlif4qngj2aif8vky54l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#security-framework-sys@2.12.0": "1dml0lp9lrvvi01s011lyss5kzzsmakaamdwsxr0431jd4l2jjpa",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#security-framework-sys@2.14.0": "0chwn01qrnvs59i5220bymd38iddy4krbnmfnhf4k451aqfj7ns9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#security-framework@2.11.1": "00ldclwx78dm61v7wkach9lcx76awlrv0fdgjdwch4dmy12j4yw9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#self_cell@0.10.3": "0pci3zh23b7dg6jmlxbn8k4plb7hcg5jprd1qiz0rp04p1ilskp1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#self_cell@1.0.4": "0jki9brixzzy032d799xspz1gikc5n2w81w8q8yyn8w6jxpsjsfk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#semver@1.0.23": "12wqpxfflclbq4dv8sa6gchdh92ahhwn4ci1ls22wlby3h57wsb1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#self_cell@1.1.0": "1gmxk5bvnnimcif7v1jk8ai2azfvh9djki545nd86vsnphjgrzf2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#semver@1.0.24": "1fmvjjkd3f64y5fqr1nakkq371mnwzv09fbz5mbmdxril63ypdiw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde@0.9.15": "1bsla8l5xr9pp5sirkal6mngxcq6q961km88jvf339j5ff8j7dil",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.210": "0flc0z8wgax1k4j5bf2zyq48bgzyv425jkd5w0i6wbh7f8j5kqy8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.210": "07yzy4wafk79ps0hmbqmsqh5xjna4pm4q57wc847bb8gl3nh4f94",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.128": "1n43nia50ybpcfmh3gcw4lcc627qsg9nyakzwgkk9pm10xklbxbg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.217": "0w2ck1p1ajmrv1cf51qf7igjn2nc51r0izzc00fzmmhkvxjl5z02",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.217": "180r3rj5gi5s1m23q66cr5wlfgc5jrs6n1mdmql2njnhk37zg6ss",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.136": "1lipcjhh1zazh283i4wsl4l14knh81q2rlkwmag8v8s2rwihqsik",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_path_to_error@0.1.16": "19hlz2359l37ifirskpcds7sxg0gzpqvfilibs7whdys0128i6dg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_spanned@0.6.8": "1q89g70azwi4ybilz5jb8prfpa575165lmrffd49vmcf76qpqq47",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1": "1zgklbdaysj3230xivihs30qi5vkhigg323a9m62k8jwf4a1qjfk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#serde_yml@0.0.12": "1p8xwz4znd6fj962y22fdvvv16gb8c0hx4iv5hjplngiidcdvqjr",
|
||||
@ -353,59 +391,66 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#signature@2.2.0": "1pi9hd5vqfr3q3k49k37z06p7gs5si0in32qia4mmr1dancr6m3p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#simd-adler32@0.3.7": "1zkq40c3iajcnr5936gjp9jjh1lpzhy44p3dq3fiw75iwr1w2vfn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#siphasher@0.2.3": "1b53m53l24lyhr505lwqzrpjyq5qfnic71mynrcfvm43rybf938b",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#siphasher@0.3.11": "03axamhmwsrmh0psdw3gf7c0zc4fyl5yjxfifz9qfka6yhkqid9q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.1": "17f35782ma3fn6sh21c027kjmd227xyrx06ffi8gw4xzv9yry6an",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#slab@0.4.9": "0rxvsgir0qw5lkycrqgb1cxsvxzjv9bmx73bk5y42svnzfba94lg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#smallvec@1.13.2": "0rsw5samawl3wsw6glrsb127rx6sh89a8wyikicw6dkdcjd1lpiw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#snowflake@1.3.0": "1wadr7bxdxbmkbqkqsvzan6q1h3mxqpxningi3ss3v9jaav7n817",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#socket2@0.5.7": "070r941wbq76xpy039an4pyiy3rfj7mp7pvibf1rcri9njq5wc6f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#socket2@0.5.8": "1s7vjmb5gzp3iaqi94rh9r63k9cj00kjgbfn7gn60kmnk6fjcw69",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#spin@0.9.8": "0rvam5r0p3a6qhc18scqpvpgb3ckzyqxpgdfyjnghh8ja7byi039",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#spki@0.7.3": "17fj8k5fmx4w9mp27l970clrh5qa7r5sjdvbsln987xhb34dc7nr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlformat@0.2.6": "14470h40gn0f6jw9xxzbpwh5qy1fgvkhkfz8xjyzgi0cvf9kmfkv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-core@0.7.4": "1xiyr35dq10sf7lq00291svcj9wbaaz1ihandjmrng9a6jlmkfi4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-macros-core@0.7.4": "1j7k0fw7n6pgabqnj6cbp8s3rmd3yvqr4chjj878cvd1m99yycsq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-macros@0.7.4": "09rih250868nfkax022y5dyk24a7qfw6scjy3sgalbzb8lihx92f",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-mysql@0.7.4": "066lxhb80xgb8r5m2yy3a7ydjvp0b6wsk9s7whwfa83d46817lqy",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-postgres@0.7.4": "0zjp30wj4n2f25dnb32vsg6jfpa3gw6dmfd0i5pr4kw91fw4x0kw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-sqlite@0.7.4": "1ap0bb2hazbrdgd7mhnckdg9xcchx0k094di9gnhpnhlhh5fyi5j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx@0.7.4": "1ahadprvyhjraq0c5712x3kdkp1gkwfm9nikrmcml2h03bzwr8n9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-core@0.8.3": "1q31dawr61wc6q2f12my4fw082mbv8sxwz1082msjsk76rlpn03a",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-macros-core@0.8.3": "1bg7sn6l8dc4pzrqx2dwc3sp7dbn97msfqahpycnl55bqnn917sf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-macros@0.8.3": "047k67sylscv0gdhwwqrn0s33jy1mvq8rmqq6s8fygv4g2ny44ii",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-mysql@0.8.3": "0czjzzjm2y6lkhxvvzrzwgp0pmlhymcnym20hn9n9kh01s7jfq25",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-postgres@0.8.3": "04wnjl51kfx0qbfsfmhqdshpmw32vzz2p8dksmj6gvb3ydbqmff5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx-sqlite@0.8.3": "0h05ca26g428h4337k4nm0ww75bcdkiqzp883m7fc92v78fsfp7q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sqlx@0.8.3": "0pvlpq0plgyxf5kikcv786pf0pjv8dx5shlvz72l510d7hxyf424",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.0": "1lxjr8q2n534b2lhkxd6l6wcddzjvnksi58zv11f9y0jjmr15wd8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#stringprep@0.1.5": "1cb3jis4h2b767csk272zw92lc6jzfzvh8d6m1cd86yqjb9z6kbv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1": "0kzvqlw8hxqb7y598w1s0hxlnmi84sg5vsipp3yg5na5d1rvba3x",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1": "14ijxaymghbl1p0wql9cib5zlwiina7kall6w7g89csprkgbvhhk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109": "0ds2if4600bd59wsv7jjgfkayfzy3hnazs394kz6zdkmna8l3dkj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#syn@2.0.79": "147mk4sgigmvsb9l8qzj199ygf0fgb0bphwdsghn8205pz82q4w9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#syn@2.0.96": "102wk3cgawimi3i0q3r3xw3i858zkyingg6y7gsxfy733amsvl6m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@0.1.2": "0q01lyj0gr9a93n10nxsn8lwbzq97jqd6b768x17c8f7v7gccir0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2": "0qvjyasd6w18mjg5xlaq5jgy84jsjfsvmnn12c13gypxbv75dwhb",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.1": "0wc9f002ia2zqcbj0q2id5x6n7g1zjqba7qkg2mr0qvvmdk7dby8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#system-configuration-sys@0.5.0": "1jckxvdr37bay3i9v52izgy52dg690x5xfg3hd394sv2xf4b2px7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#system-configuration@0.5.1": "1rz0r30xn7fiyqay2dvzfy56cvaa3km74hnbz2d72p97bkf3lfms",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#system-deps@6.2.2": "0j93ryw031n3h8b0nfpj5xwh3ify636xmv8kxianvlyyipmkbrd3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.12.16": "1cg3bnx1gdkdr5hac1hzxy64fhw4g7dqkd0n3dxy5lfngpr1mi31",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tempdir@0.3.7": "1n5n86zxpgd85y0mswrp5cfdisizq2rv3la906g6ipyc03xvbwhm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tempfile@3.13.0": "0nyagmbd4v5g6nzfydiihcn6l9j1w9bxgzyca5lyzgnhcbyckwph",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tempfile@3.15.0": "016pmkbwn3shas44gcwq1kc9lajalb90qafhiip5fvv8h6f5b2ls",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#termcolor@1.4.1": "0mappjh3fj3p2nmrg4y7qv94rchwi9mzmgmfflr8p2awdj7lyy86",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.64": "1hvzmjx9iamln854l74qyhs0jl2pg3hhqzpqm9p8gszmf9v4x408",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.64": "114s8lmssxl0c2480s671am88vzlasbaikxbvfv8pyqrq6mzh2nm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.69": "1h84fmn2nai41cxbhk6pqf46bxqq1b344v8yz089w1chzi76rvjg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.11": "1hkkn7p2y4cxbffcrprybkj0qy1rl1r6waxmxqvr764axaxc3br6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69": "0lizjay08agcr5hs9yfzzj6axs53a2rgx070a1dsi3jpkcrzbamn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.11": "1z0649rpa8c2smzx129bz4qvxmdihj30r2km6vfpcv9yny2g4lnl",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tiff@0.6.1": "0ds48vs919ccxa3fv1www7788pzkvpg434ilqkq7sjb5dmqg8lws",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tiff@0.9.1": "0ghyxlz566dzc3scvgmzys11dhq2ri77kb8sznjakijlxby104xs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.2": "1wx3qizcihw6z151hywfzzyd1y5dl804ydyxci6qm07vbakpr4pg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.18": "1kqwxvfh2jkpg38fy673d6danh1bhcmmbsmffww3mphgail2l99z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.19": "1pl558z26pp342l5y91n6dxb60xwhar975wk6jc4npiygq0ycd18",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time@0.1.45": "0nl0pzv9yf56djy8y5dx25nka5pr2q1ivlandb3d24pksgx7ly8v",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time@0.3.36": "11g8hdpahgrf1wwl2rpsg5nxq3aj7ri6xr672v4qcij6cgjqizax",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#time@0.3.37": "08bvydyc14plkwhchzia5bcdbmm0mk5fzilsdpjx06w6hf48drrm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tinystr@0.7.6": "0bxqaw7z8r2kzngxlzlgvld1r6jbnwyylyvyjbv1q71rvgaga5wi",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.8.0": "0f5rf6a2wzyv6w4jmfga9iw7rp9fp5gf4d604xgjsf3d9wgqhpj4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.8.1": "1s41rv7n39sjsxz3kd3d4adw45ndkxz1d18rfbz2wd7s9n8bhb82",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1": "081gag86208sc3y6sdkshgw3vysm5d34p431dzw0bshz66ncng0z",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.4.0": "0lnpg14h1v3fh2jvnc8cz7cjf0m7z1xgkwfpcyy632g829imjgb9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.5.0": "1f6az2xbvqp7am417b78d1za8axbvjvxnmkakz9vr8s52czx81kf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-native-tls@0.3.1": "1wkfg6zn85zckmv4im7mv20ca6b1vmlib5xwz9p7g19wjfmpdbmv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-stream@0.1.16": "1wc65gprcsyzqlr0k091glswy96kph90i32gffi4ksyh03hnqkjg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-stream@0.1.17": "0ix0770hfp4x5rh5bl7vsnr3d4iz4ms43i522xw70xaap9xqv9gc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-tungstenite@0.21.0": "0f5wj0crsx74rlll97lhw0wk6y12nhdnqvmnjx002hjn08fmcfy8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.12": "0spc0g4irbnf2flgag22gfii87avqzibwfm0si0d1g0k9ijw7rv1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio@1.40.0": "166rllhfkyqp0fs7sxn6crv74iizi4wzd3cvxkcpmlk52qip1c72",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.13": "0y0h10a52c7hrldmr3410bp7j3fadq0jn9nf7awddgd2an6smz6p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tokio@1.43.0": "17pdm49ihlhfw3rpxix3kdh2ppl1yv7nwp1kxazi5r1xz97zlq9x",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#toml@0.8.2": "0g9ysjaqvm2mv8q85xpqfn7hi710hj24sd56k49wyddvvyq8lp8q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#toml_datetime@0.6.3": "0jsy7v8bdvmzsci6imj8fzgd255fmy5fzp6zsri14yrry7i77nkw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#toml_edit@0.19.15": "08bl7rp5g6jwmfpad9s8jpw8wjrciadpnbaswgywpr9hv9qbfnqv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#toml_edit@0.20.2": "0f7k5svmxw98fhi28jpcyv7ldr2s3c867pjbji65bdxjpd44svir",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.2": "15wnvhl6cpir9125s73bqjzjsvfb0fmndmsimnl2ddnlhfvs6gs0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3": "03kq92fdzxin51w8iqix06dcfgydyvx7yr6izjq0p626v9n2l70j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3": "1hzfkvkci33ra94xjx64vv3pp0sq346w06fpkcdwjcid7zhvdycd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.27": "1rvb5dn9z6d0xdj14r403z0af0bbaqhg02hq4jc97g5wds6lqw1l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.32": "0m5aglin3cdwxpvbg6kz0r9r0k31j48n0kcfwsp6l49z26k3svf0",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.40": "1vv48dac9zgj9650pg2b4d0j3w6f3x9gbggf43scq5hrlysklln3",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tower@0.5.2": "1ybmd59nm4abl9bsvy6rx31m4zvzp5rja2slzpn712y9b68ssffh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.28": "0v92l9cxs42rdm4m5hsa8z7ln1xsiw1zc2iil8c6k7lzq0jf2nir",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.33": "170gc7cxyjx824r9kr17zc9gvzx89ypqfdzq259pr56gg5bwjwp6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.41": "1l5xrzyjfyayrwhvhldfnwdyligi1mpqm8mzbi2m1d6y6p2hlkkq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#traitobject@0.1.0": "0yb0n8822mr59j200fyr2fxgzzgqljyxflx9y8bdy3rlaqngilgg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5": "0jqijrrvm1pyq34zn1jmy2vihd4jcrjlvsh4alkjahhssjnsn8g4",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#tungstenite@0.21.0": "1qaphb5kgwgid19p64grhv2b9kxy7f1059yy92l9kwrlx90sdwcy",
|
||||
@ -414,29 +459,30 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#typemap@0.3.3": "1xm1gbvz9qisj1l6d36hrl9pw8imr8ngs6qyanjnsad3h0yfcfv5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#typenum@1.17.0": "09dqxv69m9lj9zvv6xw5vxaqx15ps0vxyy5myg33i0kbqvq0pzs2",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#typeshare-annotation@1.0.4": "0kx38ah6638pkqq5cac7nmvbg6x43v7fj5jgibla4lj8fv1dc5d6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#typeshare@1.0.3": "11riglm8incm0vq7ciyd907w1sc6frfn7h7ab0yp8bkcnycp7w84",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#typeshare@1.0.4": "1svc92lg35r12mqdpbs4wbkw7g72v2302niyw5v1w290250hzghr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unarray@0.1.4": "154smf048k84prsdgh09nkm2n0w0336v84jd4zikyn6v6jrqbspa",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unic-langid-impl@0.9.5": "1rckyn5wqd5h8jxhbzlbbagr459zkzg822r4k5n30jaryv0j4m0a",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unic-langid@0.9.5": "0i2s024frmpfa68lzy8y8vnb1rz3m9v0ga13f7h2afx7f8g9vp93",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicase@1.4.2": "0cwazh4qsmm9msckjk86zc1z35xg7hjxjykrgjalzdv367w6aivz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicase@2.7.0": "12gd74j79f94k4clxpf06l99wiv4p30wjr0qm04ihqk9zgdd9lpp",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-bidi@0.3.17": "14vqdsnrm3y5anj6h5zz5s32w88crraycblb88d9k23k9ns7vcas",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.13": "1zm1xylzsdfvm2a5ib9li3g5pp7qnkv4amhspydvgbmd9k6mc6z9",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicase@2.8.1": "0fd5ddbhpva7wrln2iah054ar2pc1drqjcll0f493vj3fv8l9f3m",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-bidi@0.3.18": "1xcxwbsqa24b8vfchhzyyzgj0l6bn51ib5v8j6krha0m77dva72w",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.14": "10ywa1pg0glgkr4l3dppjxizr9r2b7im0ycbfa0137l69z5fdfdd",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-normalization@0.1.24": "0mnrk809z3ix1wspcqy97ld5wxdb31f3xz6nsvg5qcv289ycjcsh",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-properties@0.1.3": "1l3mbgzwz8g14xcs09p4ww3hjkjcf0i1ih13nsg72bhj8n5jl3z7",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-segmentation@1.12.0": "14qla2jfx74yyb9ds3d2mpwpa4l4lzb9z57c6d2ba511458z5k7n",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode-width@0.1.14": "1bzn2zv0gp8xxbxbhifw778a7fc93pa6a1kj24jgg9msj07f7mkx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unicode_categories@0.1.1": "0kp1d7fryxxm7hqywbk88yb9d1avsam9sg76xh36k5qx2arj9v1r",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#unsafe-any@0.4.2": "0zwwphsqkw5qaiqmjwngnfpv9ym85qcsyj7adip9qplzjzbn00zk",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#url@1.7.2": "0nim1c90mxpi9wgdw2xh8dqd72vlklwlzam436akcrhjac6pqknx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#url@2.5.2": "0v2dx50mx7xzl9454cl5qmpjnhkbahmn59gd3apyipbgyyylsy12",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#url@2.5.4": "0q6sgznyy2n4l5lm16zahkisvc9nip9aa5q1pps7656xra3bdy1j",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3": "1nj99jp37k47n0hvaz5fvz7z6jd0sb4ppvfy3nphr1zbnyixpy6s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#utf-8@0.7.6": "1a9ns3fvgird0snjkd3wbdhwd3zdpc2h5gpyybrfr6ra5pkqxk09",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#utf16_iter@1.0.5": "0ik2krdr73hfgsdzw0218fn35fa09dg2hvbi1xp3bmdfrp9js8y8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4": "1gmna9flnj8dbyd8ba17zigrp9c4c3zclngf5lnb5yvz1ri41hdn",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#utf8parse@0.2.2": "088807qwjq46azicqwbhlmzwrbkz7l4hpw43sdkdyyk524vdxaq6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#uuid@0.4.0": "0cdj2v6v2yy3zyisij69waksd17cyir1n58kwyk1n622105wbzkw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#uuid@0.8.2": "1dy4ldcp7rnzjy56dxh7d2sgrcvn4q77y0a8r0a48946h66zjp5w",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#uuid@1.10.0": "0503gvp08dh5mnm3f0ffqgisj6x3mbs53dmnn1lm19pga43a1pw1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#value-bag@1.9.0": "00aij8p1n7vcggkb9nxpwx9g5nqzclrf7prd1wpi9c3sscvw312s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#uuid@1.12.0": "1i2i7ar5651d58ip1l8cghg3y60pn0rqmssvw6lm8d4s3xc1hh3l",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#value-bag@1.10.0": "1lnsixdpi1ldms1adxyafyx7lyrqxhhskgwrjckmml6majmc9x1y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#vcpkg@0.2.15": "09i4nf5y8lig6xgj3f7fyrvzd3nlaw4znrihw8psidvv5yk4xkdc",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#version-compare@0.2.0": "12y9262fhjm1wp0aj3mwhads7kv0jz8h168nn5fb8b43nwf9abl5",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#version_check@0.1.5": "1pf91pvj8n6akh7w6j5ypka6aqz08b3qpzgs0ak2kjf4frkiljwi",
|
||||
@ -447,13 +493,13 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasi@0.10.0+wasi-snapshot-preview1": "07y3l8mzfzzz4cj09c8y90yak4hpsi9g7pllyzpr6xvwrabka50s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasi@0.11.0+wasi-snapshot-preview1": "08z4hxwkpdpalxjps1ai9y7ihin26y9f476i53dv98v45gkqg3cw",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasite@0.1.0": "0nw5h9nmcl4fyf4j5d4mfdjfgvwi1cakpi349wc4zrr59wxxinmq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-backend@0.2.93": "0yypblaf94rdgqs5xw97499xfwgs1096yx026d6h88v563d9dqwx",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-futures@0.4.43": "1vf8kmaj95xn5893y1bdlav47y5niq85q5bms9pfj8d6cc7k1sb1",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-macro-support@0.2.93": "0dp8w6jmw44srym6l752nkr3hkplyw38a2fxz5f3j1ch9p3l1hxg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-macro@0.2.93": "1kycd1xfx4d9xzqknvzbiqhwb5fzvjqrrn88x692q1vblj8lqp2q",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-shared@0.2.93": "1104bny0hv40jfap3hp8jhs0q4ya244qcrvql39i38xlghq0lan6",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen@0.2.93": "1dfr7pka5kwvky2fx82m9d060p842hc5fyyw8igryikcdb0xybm8",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#web-sys@0.3.70": "1h1jspkqnrx1iybwhwhc3qq8c8fn4hy5jcf0wxjry4mxv6pymz96",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-backend@0.2.100": "1ihbf1hq3y81c4md9lyh6lcwbx6a5j0fw4fygd423g62lm8hc2ig",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-futures@0.4.50": "0q8ymi6i9r3vxly551dhxcyai7nc491mspj0j1wbafxwq074fpam",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-macro-support@0.2.100": "1plm8dh20jg2id0320pbmrlsv6cazfv6b6907z19ys4z1jj7xs4a",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-macro@0.2.100": "01xls2dvzh38yj17jgrbiib1d3nyad7k2yw9s0mpklwys333zrkz",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen-shared@0.2.100": "0gffxvqgbh9r9xl36gprkfnh3w9gl8wgia6xrin7v11sjcxxf18s",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#wasm-bindgen@0.2.100": "1x8ymcm6yi3i1rwj78myl1agqv2m86i648myy3lc97s9swlqkp0y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#web-sys@0.3.77": "1lnmc1ffbq34qw91nndklqqm75rasaffj2g4f8h1yvqqz4pdvdik",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#weezl@0.1.8": "10lhndjgs6y5djpg3b420xngcr6jkmv70q8rb1qcicbily35pa2k",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#whoami@1.5.2": "0vdvm6sga4v9515l6glqqfnmzp246nq66dd09cw5ri4fyn3mnb9p",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#winapi-i686-pc-windows-gnu@0.4.0": "1dmpa6mvcvzz16zg6d5vrfy4bxgg541wxrcip7cnshi06v38ffxc",
|
||||
@ -483,9 +529,18 @@
|
||||
"registry+https://github.com/rust-lang/crates.io-index#windows_x86_64_msvc@0.52.6": "1v7rb5cibyzx8vak29pdrk8nx9hycsjs4w0jgms08qk49jl6v7sq",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#winnow@0.5.40": "0xk8maai7gyxda673mmw3pj1hdizy5fpi7287vaywykkk19sk4zm",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#winreg@0.50.0": "1cddmp929k882mdh6i9f2as848f13qqna6czwsqzkh1pqnr5fkjj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#write16@1.0.0": "0dnryvrrbrnl7vvf5vb1zkmwldhjkf2n5znliviam7bm4900z2fi",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#writeable@0.5.5": "0lawr6y0bwqfyayf3z8zmqlhpnzhdx0ahs54isacbhyjwa7g778y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#yansi-term@0.1.2": "1w8vjlvxba6yvidqdvxddx3crl6z66h39qxj8xi6aqayw2nk0p7y",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#yansi@1.0.1": "0jdh55jyv0dpd38ij4qh60zglbw9aa8wafqai6m0wa7xaxk3mrfg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#yoke-derive@0.7.5": "0m4i4a7gy826bfvnqa9wy6sp90qf0as3wps3wb0smjaamn68g013",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#yoke@0.7.5": "0h3znzrdmll0a7sglzf9ji0p5iqml11wrj1dypaf6ad6kbpnl3hj",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerocopy-derive@0.7.35": "0gnf2ap2y92nwdalzz3x7142f2b83sni66l39vxp2ijd6j080kzs",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.7.35": "1w36q7b9il2flg0qskapgi9ymgg7p985vniqd09vi0mwib8lz6qv",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerofrom-derive@0.1.5": "022q55phhb44qbrcfbc48k0b741fl8gnazw3hpmmndbx5ycfspjr",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.5": "0bnd8vjcllzrvr3wvn8x14k2hkrpyy1fm3crkn2y3plmr44fxwyg",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.1": "1pjdrmjwmszpxfd7r860jx54cyk94qk59x13sc307cvr5256glyf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerovec-derive@0.10.3": "1ik322dys6wnap5d3gcsn09azmssq466xryn5czfm13mn7gsdbvf",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zerovec@0.10.4": "0yghix7n3fjfdppwghknzvx9v8cf826h2qal5nqvy8yzg4yqjaxa",
|
||||
"registry+https://github.com/rust-lang/crates.io-index#zune-inflate@0.2.54": "00kg24jh3zqa3i6rg6yksnb71bch9yi1casqydl00s7nw8pk7avk"
|
||||
}
|
@ -12,9 +12,9 @@ use std::{
|
||||
|
||||
use cairo::{Context, Rectangle};
|
||||
use cyberpunk::{AsymLine, AsymLineCutout, GlowPen, Pen, Text};
|
||||
use glib::{GString, Object};
|
||||
use glib::Object;
|
||||
use gtk::{
|
||||
glib::{self, Propagation},
|
||||
glib::{self},
|
||||
prelude::*,
|
||||
subclass::prelude::*,
|
||||
EventControllerKey,
|
||||
@ -40,6 +40,7 @@ struct Step {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Default)]
|
||||
struct Script(Vec<Step>);
|
||||
|
||||
impl Script {
|
||||
@ -51,7 +52,7 @@ impl Script {
|
||||
Ok(Self(script))
|
||||
}
|
||||
|
||||
fn iter<'a>(&'a self) -> impl Iterator<Item = &'a Step> {
|
||||
fn iter(&self) -> impl Iterator<Item = &'_ Step> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
@ -60,11 +61,6 @@ impl Script {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Script {
|
||||
fn default() -> Self {
|
||||
Self(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Script {
|
||||
type Output = Step;
|
||||
@ -98,11 +94,11 @@ impl Animation for Fade {
|
||||
let alpha_rate: f64 = 1. / total_frames as f64;
|
||||
|
||||
let frames = (now - self.start_time).as_secs_f64() * FPS as f64;
|
||||
let alpha = alpha_rate * frames as f64;
|
||||
let alpha = alpha_rate * frames;
|
||||
|
||||
let text_display = Text::new(self.text.clone(), context, 64., width);
|
||||
let _ = context.move_to(0., text_display.extents().height());
|
||||
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
|
||||
context.move_to(0., text_display.extents().height());
|
||||
context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
|
||||
text_display.draw();
|
||||
}
|
||||
}
|
||||
@ -126,16 +122,16 @@ impl Animation for CrossFade {
|
||||
let alpha_rate: f64 = 1. / total_frames as f64;
|
||||
|
||||
let frames = (now - self.start_time).as_secs_f64() * FPS as f64;
|
||||
let alpha = alpha_rate * frames as f64;
|
||||
let alpha = alpha_rate * frames;
|
||||
|
||||
let text_display = Text::new(self.old_text.clone(), context, 64., width);
|
||||
let _ = context.move_to(0., text_display.extents().height());
|
||||
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, 1. - alpha);
|
||||
context.move_to(0., text_display.extents().height());
|
||||
context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, 1. - alpha);
|
||||
text_display.draw();
|
||||
|
||||
let text_display = Text::new(self.new_text.clone(), context, 64., width);
|
||||
let _ = context.move_to(0., text_display.extents().height());
|
||||
let _ = context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
|
||||
context.move_to(0., text_display.extents().height());
|
||||
context.set_source_rgba(PURPLE.0, PURPLE.1, PURPLE.2, alpha);
|
||||
text_display.draw();
|
||||
}
|
||||
}
|
||||
@ -163,9 +159,7 @@ impl Default for CyberScreenState {
|
||||
|
||||
impl CyberScreenState {
|
||||
fn new(script: Script) -> CyberScreenState {
|
||||
let mut s = CyberScreenState::default();
|
||||
s.script = script;
|
||||
s
|
||||
CyberScreenState { script, ..Default::default() }
|
||||
}
|
||||
|
||||
fn next_page(&mut self) -> Box<dyn Animation> {
|
||||
@ -260,7 +254,7 @@ impl CyberScreen {
|
||||
let s = s.clone();
|
||||
move |_, context, width, height| {
|
||||
let now = Instant::now();
|
||||
let _ = context.set_source_rgb(0., 0., 0.);
|
||||
context.set_source_rgb(0., 0., 0.);
|
||||
let _ = context.paint();
|
||||
|
||||
let pen = GlowPen::new(width, height, 2., 8., (0.7, 0., 1.));
|
||||
@ -293,7 +287,7 @@ impl CyberScreen {
|
||||
let _ = context.set_source(tracery);
|
||||
let _ = context.paint();
|
||||
|
||||
let mut animations = s.imp().animations.borrow_mut();
|
||||
let animations = s.imp().animations.borrow_mut();
|
||||
|
||||
let lr_margin = 50.;
|
||||
let max_width = width as f64 - lr_margin * 2.;
|
||||
|
@ -7,6 +7,7 @@ license = "GPL-3.0-only"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-std = "1.13.0"
|
||||
cairo-rs = { version = "0.18" }
|
||||
cyberpunk = { path = "../cyberpunk" }
|
||||
gio = { version = "0.18" }
|
||||
|
@ -1,5 +1,5 @@
|
||||
use cairo::{
|
||||
Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern,
|
||||
Context, FontSlant, FontWeight, Format, ImageSurface, LinearGradient, Pattern,
|
||||
TextExtents,
|
||||
};
|
||||
use cyberpunk::{AsymLine, AsymLineCutout, GlowPen, Pen, SlashMeter};
|
||||
@ -497,8 +497,7 @@ fn main() {
|
||||
});
|
||||
|
||||
app.connect_activate(move |app| {
|
||||
let (gtk_tx, gtk_rx) =
|
||||
gtk::glib::MainContext::channel::<State>(gtk::glib::Priority::DEFAULT);
|
||||
let (gtk_tx, gtk_rx) = async_std::channel::unbounded();
|
||||
|
||||
let window = gtk::ApplicationWindow::new(app);
|
||||
window.present();
|
||||
@ -529,19 +528,25 @@ fn main() {
|
||||
});
|
||||
window.add_controller(keyboard_events);
|
||||
|
||||
gtk_rx.attach(None, move |state| {
|
||||
glib::spawn_future_local({
|
||||
let splash = splash.clone();
|
||||
async move {
|
||||
while let Ok(state) = gtk_rx.recv().await {
|
||||
println!("received state");
|
||||
splash.set_state(state);
|
||||
glib::ControlFlow::Continue
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
std::thread::spawn({
|
||||
glib::spawn_future_local({
|
||||
let state = state.clone();
|
||||
move || {
|
||||
async move {
|
||||
state.write().unwrap().start();
|
||||
loop {
|
||||
std::thread::sleep(Duration::from_millis(1000 / 60));
|
||||
async_std::task::sleep(Duration::from_millis(1000 / 60)).await;
|
||||
state.write().unwrap().run(Instant::now());
|
||||
let _ = gtk_tx.send(*state.read().unwrap());
|
||||
println!("state: {:?}", state.read().unwrap());
|
||||
let _ = gtk_tx.send(*state.read().unwrap()).await;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -274,7 +274,7 @@ impl<'a> Text<'a> {
|
||||
for line in self.content.iter() {
|
||||
baseline += self.context.text_extents(line).unwrap().height() + 10.;
|
||||
self.context.move_to(0., baseline);
|
||||
let _ = self.context.show_text(&line);
|
||||
let _ = self.context.show_text(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,7 +294,7 @@ fn word_wrap(content: String, context: &Context, max_width: f64) -> Vec<String>
|
||||
lines.push(line.clone());
|
||||
}
|
||||
}
|
||||
if line.len() > 0 {
|
||||
if !line.is_empty() {
|
||||
lines.push(line);
|
||||
}
|
||||
lines
|
||||
|
@ -31,7 +31,9 @@ impl ApplicationWindow {
|
||||
|
||||
let provider = gtk::CssProvider::new();
|
||||
provider.load_from_data(&stylesheet);
|
||||
#[allow(deprecated)]
|
||||
let context = window.style_context();
|
||||
#[allow(deprecated)]
|
||||
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
let layout = gtk::Box::builder()
|
||||
|
@ -36,6 +36,7 @@ impl Default for TransitClock {
|
||||
s.set_draw_func({
|
||||
let s = s.clone();
|
||||
move |_, context, width, height| {
|
||||
#[allow(deprecated)]
|
||||
let style_context = WidgetExt::style_context(&s);
|
||||
let center_x = width as f64 / 2.;
|
||||
let center_y = height as f64 / 2.;
|
||||
@ -45,7 +46,9 @@ impl Default for TransitClock {
|
||||
let sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
|
||||
let sunset = info.sunset - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
|
||||
|
||||
#[allow(deprecated)]
|
||||
let night_color = style_context.lookup_color("dark_5").unwrap();
|
||||
#[allow(deprecated)]
|
||||
let day_color = style_context.lookup_color("blue_1").unwrap();
|
||||
|
||||
PieChart::new(&style_context)
|
||||
|
@ -1,5 +1,7 @@
|
||||
use cairo::Context;
|
||||
use gtk::{gdk::RGBA, prelude::*, StyleContext};
|
||||
use gtk::{gdk::RGBA, prelude::*};
|
||||
#[allow(deprecated)]
|
||||
use gtk::StyleContext;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -27,7 +29,9 @@ pub struct PieChart {
|
||||
}
|
||||
|
||||
impl PieChart {
|
||||
#[allow(deprecated)]
|
||||
pub fn new(style_context: &StyleContext) -> Self {
|
||||
#[allow(deprecated)]
|
||||
Self {
|
||||
rotation: 0.,
|
||||
wedges: vec![],
|
||||
|
@ -132,7 +132,7 @@ impl SolunaClient {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use serde_json;
|
||||
|
||||
|
||||
const EXAMPLE: &str = "{\"sunRise\":\"7:15\",\"sunTransit\":\"12:30\",\"sunSet\":\"17:45\",\"moonRise\":null,\"moonTransit\":\"7:30\",\"moonUnder\":\"19:54\",\"moonSet\":\"15:02\",\"moonPhase\":\"Waning Crescent\",\"moonIllumination\":0.35889454647387764,\"sunRiseDec\":7.25,\"sunTransitDec\":12.5,\"sunSetDec\":17.75,\"moonRiseDec\":null,\"moonSetDec\":15.033333333333333,\"moonTransitDec\":7.5,\"moonUnderDec\":19.9,\"minor1Start\":null,\"minor1Stop\":null,\"minor2StartDec\":14.533333333333333,\"minor2Start\":\"14:32\",\"minor2StopDec\":15.533333333333333,\"minor2Stop\":\"15:32\",\"major1StartDec\":6.5,\"major1Start\":\"06:30\",\"major1StopDec\":8.5,\"major1Stop\":\"08:30\",\"major2StartDec\":18.9,\"major2Start\":\"18:54\",\"major2StopDec\":20.9,\"major2Stop\":\"20:54\",\"dayRating\":1,\"hourlyRating\":{\"0\":20,\"1\":20,\"2\":0,\"3\":0,\"4\":0,\"5\":0,\"6\":20,\"7\":40,\"8\":40,\"9\":20,\"10\":0,\"11\":0,\"12\":0,\"13\":0,\"14\":0,\"15\":20,\"16\":20,\"17\":20,\"18\":40,\"19\":20,\"20\":20,\"21\":20,\"22\":0,\"23\":0}}";
|
||||
|
||||
|
@ -9,6 +9,7 @@ documentation = "https://docs.rs/emseries"
|
||||
homepage = "https://github.com/luminescent-dreams/emseries"
|
||||
repository = "https://github.com/luminescent-dreams/emseries"
|
||||
categories = ["database-implementations"]
|
||||
edition = "2021"
|
||||
|
||||
include = [
|
||||
"**/*.rs",
|
||||
|
@ -10,7 +10,7 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but
|
||||
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use types::{Recordable, Timestamp};
|
||||
use crate::types::{Recordable, Timestamp};
|
||||
|
||||
/// This trait is used for constructing queries for searching the database.
|
||||
pub trait Criteria {
|
||||
|
@ -10,10 +10,6 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but
|
||||
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate uuid;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::ser::Serialize;
|
||||
use std::cmp::Ordering;
|
||||
@ -24,8 +20,8 @@ use std::fs::OpenOptions;
|
||||
use std::io::{BufRead, BufReader, LineWriter, Write};
|
||||
use std::iter::Iterator;
|
||||
|
||||
use criteria::Criteria;
|
||||
use types::{EmseriesReadError, EmseriesWriteError, Record, RecordId, Recordable};
|
||||
use crate::criteria::Criteria;
|
||||
use crate::types::{EmseriesReadError, EmseriesWriteError, Record, RecordId, Recordable};
|
||||
|
||||
// A RecordOnDisk, a private data structure, is useful for handling all of the on-disk
|
||||
// representations of a record. Unlike [Record], this one can accept an empty data value to
|
||||
|
11
file-service/Taskfile.yml
Normal file
11
file-service/Taskfile.yml
Normal file
@ -0,0 +1,11 @@
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- cargo build
|
||||
|
||||
lint:
|
||||
cmds:
|
||||
- cargo watch -x clippy
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use build_html::{self, Html, HtmlContainer};
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
@ -23,13 +25,14 @@ impl FromIterator<(&str, &str)> for Attributes {
|
||||
}
|
||||
*/
|
||||
|
||||
impl ToString for Attributes {
|
||||
fn to_string(&self) -> String {
|
||||
self.0
|
||||
impl Display for Attributes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let result = self.0
|
||||
.iter()
|
||||
.map(|(key, value)| format!("{}=\"{}\"", key, value))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
.join(" ");
|
||||
write!(f, "{}", result)
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +205,7 @@ impl Html for Button {
|
||||
"<button {ty} {name} {attrs}>{label}</button>",
|
||||
name = name,
|
||||
label = self.label,
|
||||
attrs = self.attributes.to_string()
|
||||
attrs = self.attributes
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -118,17 +118,21 @@ impl Deref for FileId {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub trait FileRoot {
|
||||
fn root(&self) -> PathBuf;
|
||||
}
|
||||
*/
|
||||
|
||||
pub struct Context(PathBuf);
|
||||
// pub struct Context(PathBuf);
|
||||
|
||||
/*
|
||||
impl FileRoot for Context {
|
||||
fn root(&self) -> PathBuf {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub struct Store {
|
||||
files_root: PathBuf,
|
||||
|
@ -153,7 +153,7 @@ mod test {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn it_allows_valid_dates() {
|
||||
let reference = chrono::NaiveDate::from_ymd_opt(2006, 01, 02).unwrap();
|
||||
let reference = chrono::NaiveDate::from_ymd_opt(2006, 1, 2).unwrap();
|
||||
let field = DateField::new(reference);
|
||||
field.imp().year.set_value(Some(2023));
|
||||
field.imp().month.set_value(Some(10));
|
||||
|
@ -80,10 +80,10 @@ impl TimeFormatter {
|
||||
0 => Err(ParseError),
|
||||
1 => Err(ParseError),
|
||||
2 => chrono::NaiveTime::from_hms_opt(parts[0], parts[1], 0)
|
||||
.map(|v| TimeFormatter(v))
|
||||
.map(TimeFormatter)
|
||||
.ok_or(ParseError),
|
||||
3 => chrono::NaiveTime::from_hms_opt(parts[0], parts[1], parts[2])
|
||||
.map(|v| TimeFormatter(v))
|
||||
.map(TimeFormatter)
|
||||
.ok_or(ParseError),
|
||||
_ => Err(ParseError),
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ mod test {
|
||||
async fn put_record(&self, record: TraxRecord) -> Result<RecordId, WriteError> {
|
||||
let id = RecordId::default();
|
||||
let record = Record {
|
||||
id: id,
|
||||
id,
|
||||
data: record,
|
||||
};
|
||||
self.put_records.write().unwrap().push(record.clone());
|
||||
@ -509,7 +509,7 @@ mod test {
|
||||
Record {
|
||||
id: RecordId::default(),
|
||||
data: TraxRecord::TimeDistance(ft_core::TimeDistance {
|
||||
datetime: oct_13_am.clone(),
|
||||
datetime: oct_13_am,
|
||||
activity: TimeDistanceActivity::Biking,
|
||||
distance: Some(15000. * si::M),
|
||||
duration: Some(3600. * si::S),
|
||||
|
@ -144,7 +144,7 @@ impl HistoricalView {
|
||||
let mut model = gio::ListStore::new::<Date>();
|
||||
let mut days = interval.days().map(Date::new).collect::<Vec<Date>>();
|
||||
days.reverse();
|
||||
model.extend(days.into_iter());
|
||||
model.extend(days);
|
||||
self.imp()
|
||||
.list_view
|
||||
.set_model(Some(>k::NoSelection::new(Some(model))));
|
||||
|
@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with Fit
|
||||
use chrono::SecondsFormat;
|
||||
use chrono_tz::Etc::UTC;
|
||||
use dimensioned::si;
|
||||
use emseries::{Record, RecordId, Series, Timestamp};
|
||||
use emseries::{Record, RecordId};
|
||||
use ft_core::{self, DurationWorkout, DurationWorkoutActivity, SetRepActivity, TraxRecord};
|
||||
use serde::{
|
||||
de::{self, Visitor},
|
||||
@ -26,7 +26,7 @@ use serde::{
|
||||
use std::{
|
||||
fmt,
|
||||
fs::File,
|
||||
io::{BufRead, BufReader, Read},
|
||||
io::{BufRead, BufReader},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
|
@ -86,7 +86,7 @@
|
||||
cyber-slides = cargo_nix.workspaceMembers.cyber-slides.build;
|
||||
cyberpunk-splash = cargo_nix.workspaceMembers.cyberpunk-splash.build;
|
||||
dashboard = cargo_nix.workspaceMembers.dashboard.build;
|
||||
file-service = cargo_nix.workspaceMembers.file-service.build;
|
||||
# file-service = cargo_nix.workspaceMembers.file-service.build;
|
||||
fitnesstrax = cargo_nix.workspaceMembers.fitnesstrax.build;
|
||||
otg-gtk = cargo_nix.workspaceMembers.otg-gtk.build;
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
cyber-slides
|
||||
cyberpunk-splash
|
||||
dashboard
|
||||
file-service
|
||||
# file-service
|
||||
fitnesstrax
|
||||
otg-gtk
|
||||
];
|
||||
|
@ -294,21 +294,21 @@ mod tests {
|
||||
use fluent_bundle::{FluentArgs, FluentValue};
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
const EN_TRANSLATIONS: &'static str = "
|
||||
const EN_TRANSLATIONS: &str = "
|
||||
preferences = Preferences
|
||||
history = History
|
||||
time_display = {$time} during the day
|
||||
nested_display = nesting a time display: {time_display}
|
||||
";
|
||||
|
||||
const EO_TRANSLATIONS: &'static str = "
|
||||
const EO_TRANSLATIONS: &str = "
|
||||
history = Historio
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn translations() {
|
||||
let en_id = "en-US".parse::<LanguageIdentifier>().unwrap();
|
||||
let mut fluent = FluentErgo::new(&vec![en_id.clone()]);
|
||||
let mut fluent = FluentErgo::new(&[en_id.clone()]);
|
||||
fluent
|
||||
.add_from_text(en_id, String::from(EN_TRANSLATIONS))
|
||||
.expect("text should load");
|
||||
@ -322,7 +322,7 @@ history = Historio
|
||||
fn translation_fallback() {
|
||||
let eo_id = "eo".parse::<LanguageIdentifier>().unwrap();
|
||||
let en_id = "en".parse::<LanguageIdentifier>().unwrap();
|
||||
let mut fluent = FluentErgo::new(&vec![eo_id.clone(), en_id.clone()]);
|
||||
let mut fluent = FluentErgo::new(&[eo_id.clone(), en_id.clone()]);
|
||||
fluent
|
||||
.add_from_text(en_id, String::from(EN_TRANSLATIONS))
|
||||
.expect("text should load");
|
||||
@ -342,7 +342,7 @@ history = Historio
|
||||
#[test]
|
||||
fn placeholder_insertion_should_strip_placeholder_markers() {
|
||||
let en_id = "en".parse::<LanguageIdentifier>().unwrap();
|
||||
let mut fluent = FluentErgo::new(&vec![en_id.clone()]);
|
||||
let mut fluent = FluentErgo::new(&[en_id.clone()]);
|
||||
fluent
|
||||
.add_from_text(en_id, String::from(EN_TRANSLATIONS))
|
||||
.expect("text should load");
|
||||
@ -357,7 +357,7 @@ history = Historio
|
||||
#[test]
|
||||
fn placeholder_insertion_should_strip_nested_placeholder_markers() {
|
||||
let en_id = "en".parse::<LanguageIdentifier>().unwrap();
|
||||
let mut fluent = FluentErgo::new(&vec![en_id.clone()]);
|
||||
let mut fluent = FluentErgo::new(&[en_id.clone()]);
|
||||
fluent
|
||||
.add_from_text(en_id, String::from(EN_TRANSLATIONS))
|
||||
.expect("text should load");
|
||||
|
@ -7,8 +7,8 @@ use std::iter::Iterator;
|
||||
#[derive(Clone)]
|
||||
pub struct ApplicationWindow {
|
||||
pub window: adw::ApplicationWindow,
|
||||
pub layout: gtk::FlowBox,
|
||||
pub playlists: Vec<PlaylistCard>,
|
||||
// pub layout: gtk::FlowBox,
|
||||
// pub playlists: Vec<PlaylistCard>,
|
||||
}
|
||||
|
||||
impl ApplicationWindow {
|
||||
@ -31,7 +31,9 @@ impl ApplicationWindow {
|
||||
|
||||
let provider = gtk::CssProvider::new();
|
||||
provider.load_from_data(&stylesheet);
|
||||
#[allow(deprecated)]
|
||||
let context = window.style_context();
|
||||
#[allow(deprecated)]
|
||||
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
let layout = gtk::FlowBox::new();
|
||||
@ -57,8 +59,10 @@ impl ApplicationWindow {
|
||||
|
||||
Self {
|
||||
window,
|
||||
/*
|
||||
layout,
|
||||
playlists,
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ impl State {
|
||||
|
||||
fn add_audio(&self, device: String) {
|
||||
let mut st = self.internal.write().unwrap();
|
||||
(*st).device_list.push(device);
|
||||
st.device_list.push(device);
|
||||
}
|
||||
|
||||
fn audio_devices(&self) -> Vec<String> {
|
||||
let st = self.internal.read().unwrap();
|
||||
(*st).device_list.clone()
|
||||
st.device_list.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,8 +107,6 @@ impl ObjectSubclass for HexGridWindowPrivate {
|
||||
layout.append(&drawing_area);
|
||||
layout.append(&sidebar);
|
||||
|
||||
layout.show();
|
||||
|
||||
Self {
|
||||
drawing_area,
|
||||
hex_address,
|
||||
|
400
ifc/Cargo.lock
generated
400
ifc/Cargo.lock
generated
@ -1,400 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "international-fixed-calendar"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
@ -1,14 +0,0 @@
|
||||
[package]
|
||||
name = "ifc"
|
||||
description = "chrono-compatible-ish date objects for the International Fixed Calendar"
|
||||
version = "0.1.0"
|
||||
authors = ["Savanni D'Gerinel <savanni@luminescent-dreams.com>"]
|
||||
edition = "2018"
|
||||
keywords = ["date", "time", "calendar"]
|
||||
categories = ["date-and-time"]
|
||||
license = "GPL-3.0-only"
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
thiserror = { version = "1" }
|
@ -1,8 +0,0 @@
|
||||
# International Fixed Calendar
|
||||
|
||||
This is a fun project implementing a library for the [International Fixed Calendar](https://en.wikipedia.org/wiki/International_Fixed_Calendar).
|
||||
|
||||
This is at least somewhat compatible with [Chrono](https://github.com/chronotope/chrono), in that I have implemented these traits:
|
||||
|
||||
* `From<NaiveDate>`
|
||||
* `Datelike`
|
1042
ifc/src/lib.rs
1042
ifc/src/lib.rs
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title> {{month}} {{year}} </title>
|
||||
<link href="/css" rel="stylesheet" type="text/css" media="screen" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1> IFC Fixed Calendar: {{month}}, {{year}} years after the invention of agriculture </h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Sunday </th>
|
||||
<th> Monday </th>
|
||||
<th> Tuesday </th>
|
||||
<th> Wednesday </th>
|
||||
<th> Thursday </th>
|
||||
<th> Friday </th>
|
||||
<th> Saturday </th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{{#weeks}}
|
||||
<tr>
|
||||
{{#days}}
|
||||
<td class="{{highlight}}"> {{day}} </td>
|
||||
{{/days}}
|
||||
</tr>
|
||||
{{/weeks}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,35 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>{{month}} {{year}}</title>
|
||||
<link href="/css" rel="stylesheet" type="text/css" media="screen" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
IFC Fixed Calendar: {{month}}, {{year}} years after the invention of
|
||||
agriculture
|
||||
</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Sunday</th>
|
||||
<th>Monday</th>
|
||||
<th>Tuesday</th>
|
||||
<th>Wednesday</th>
|
||||
<th>Thursday</th>
|
||||
<th>Friday</th>
|
||||
<th>Saturday</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{{#weeks}}
|
||||
<tr>
|
||||
{{#days}}
|
||||
<td class="{{highlight}}">{{day}}</td>
|
||||
{{/days}}
|
||||
</tr>
|
||||
{{/weeks}}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>{{day_out_of_time}} {{year}}</title>
|
||||
<link href="/css" rel="stylesheet" type="text/css" media="screen" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
IFC Fixed Calendar: {{day_out_of_time}}, {{year}} years after the
|
||||
invention of agriculture
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
@ -1,18 +0,0 @@
|
||||
|
||||
table {
|
||||
width: 98%;
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
width: 14%;
|
||||
font-family: sans-serif;
|
||||
font-size: larger;
|
||||
border: 1px solid black;
|
||||
padding: 1em 0em 5em 1em;
|
||||
}
|
||||
|
||||
.today {
|
||||
background-color: rgb(200, 200, 255);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
Copyright 2020-2023, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of the Luminescent Dreams Tools.
|
||||
|
||||
Luminescent Dreams Tools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
Luminescent Dreams Tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate chrono;
|
||||
extern crate chrono_tz;
|
||||
extern crate ifc as IFC;
|
||||
|
||||
use chrono::{Datelike, Utc};
|
||||
|
||||
fn main() {
|
||||
let d = IFC::IFC::from(Utc::today());
|
||||
println!("{} {}, {}", d.month(), d.day(), d.year());
|
||||
}
|
119
ifc/src/web.rs
119
ifc/src/web.rs
@ -1,119 +0,0 @@
|
||||
/*
|
||||
Copyright 2020-2023, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of the Luminescent Dreams Tools.
|
||||
|
||||
Luminescent Dreams Tools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
Luminescent Dreams Tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use chrono::{Datelike, Utc};
|
||||
use ifc as IFC;
|
||||
use iron::headers;
|
||||
use iron::middleware::Handler;
|
||||
use iron::modifiers::Header;
|
||||
use iron::prelude::*;
|
||||
use iron::status;
|
||||
use mustache::{compile_str, Template};
|
||||
use router::Router;
|
||||
use serde::Serialize;
|
||||
|
||||
pub const STYLES: &'static str = include_str!("static/styles.css");
|
||||
pub const INDEX: &'static str = include_str!("static/index.html");
|
||||
|
||||
pub struct IndexHandler {
|
||||
pub template: Template,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DayEntry {
|
||||
day: u8,
|
||||
highlight: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Week {
|
||||
days: Vec<DayEntry>,
|
||||
}
|
||||
|
||||
impl Week {
|
||||
fn new(start_day: u8, today: u8) -> Week {
|
||||
Week {
|
||||
days: (1..8)
|
||||
.map(|d| DayEntry {
|
||||
day: d + start_day,
|
||||
highlight: if today == (d + start_day) {
|
||||
String::from("today")
|
||||
} else {
|
||||
String::from("")
|
||||
},
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct IndexTemplateParams {
|
||||
month: String,
|
||||
year: i32,
|
||||
weeks: Vec<Week>,
|
||||
}
|
||||
|
||||
impl IndexTemplateParams {
|
||||
fn new(date: IFC::IFC) -> IndexTemplateParams {
|
||||
let day = date.day() as u8;
|
||||
IndexTemplateParams {
|
||||
month: String::from(IFC::Month::from(date.month())),
|
||||
year: date.year(),
|
||||
weeks: (0..4).map(|wn| Week::new(wn * 7, day)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler for IndexHandler {
|
||||
fn handle(&self, _: &mut Request) -> IronResult<Response> {
|
||||
let d = IFC::IFC::from(Utc::today());
|
||||
Ok(Response::with((
|
||||
status::Ok,
|
||||
Header(headers::ContentType(iron::mime::Mime(
|
||||
iron::mime::TopLevel::Text,
|
||||
iron::mime::SubLevel::Html,
|
||||
vec![],
|
||||
))),
|
||||
self.template
|
||||
.render_to_string(&IndexTemplateParams::new(d))
|
||||
.expect("the template to render"),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn css(_: &mut Request) -> IronResult<Response> {
|
||||
Ok(Response::with((
|
||||
status::Ok,
|
||||
Header(headers::ContentType(iron::mime::Mime(
|
||||
iron::mime::TopLevel::Text,
|
||||
iron::mime::SubLevel::Css,
|
||||
vec![],
|
||||
))),
|
||||
STYLES,
|
||||
)))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut router = Router::new();
|
||||
router.get(
|
||||
"/",
|
||||
IndexHandler {
|
||||
template: compile_str(INDEX).expect("the template to compile"),
|
||||
},
|
||||
"index",
|
||||
);
|
||||
|
||||
router.get("/css", css, "styles");
|
||||
|
||||
Iron::new(router).http("127.0.0.1:3000").unwrap();
|
||||
}
|
@ -78,7 +78,7 @@ mod tests {
|
||||
})
|
||||
.await;
|
||||
assert_eq!(value, Value(16));
|
||||
assert_eq!(*run.read().unwrap(), true);
|
||||
assert!(*run.read().unwrap());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -97,6 +97,6 @@ mod tests {
|
||||
})
|
||||
.await;
|
||||
assert_eq!(value, Value(15));
|
||||
assert_eq!(*run.read().unwrap(), false);
|
||||
assert!(!(*run.read().unwrap()));
|
||||
}
|
||||
}
|
||||
|
@ -80,12 +80,12 @@ mod tests {
|
||||
use super::*;
|
||||
use cool_asserts::assert_matches;
|
||||
|
||||
const DATA: &'static str = "15";
|
||||
const DATA: &str = "15";
|
||||
|
||||
#[test]
|
||||
fn function() {
|
||||
let resp = parse_number_a::<nom::error::VerboseError<&str>>()
|
||||
.map(|val| Container(val))
|
||||
.map(Container)
|
||||
.parse(DATA);
|
||||
assert_matches!(resp, Ok((_, content)) =>
|
||||
assert_eq!(content, Container(15))
|
||||
@ -95,7 +95,7 @@ mod tests {
|
||||
#[test]
|
||||
fn parser() {
|
||||
let resp = parse_number_b::<nom::error::VerboseError<&str>>()
|
||||
.map(|val| Container(val))
|
||||
.map(Container)
|
||||
.parse(DATA);
|
||||
assert_matches!(resp, Ok((_, content)) =>
|
||||
assert_eq!(content, Container(15))
|
||||
|
@ -396,8 +396,7 @@ mod test {
|
||||
(Coordinate { column: 17, row: 0 }, Color::White),
|
||||
(Coordinate { column: 17, row: 1 }, Color::White),
|
||||
(Coordinate { column: 18, row: 1 }, Color::White),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
test(board);
|
||||
@ -436,33 +435,32 @@ mod test {
|
||||
},
|
||||
Color::Black,
|
||||
),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
assert!(board.group(&Coordinate { column: 18, row: 3 }).is_none());
|
||||
assert_eq!(
|
||||
board
|
||||
.group(&Coordinate { column: 3, row: 3 })
|
||||
.map(|g| board.liberties(&g)),
|
||||
.map(|g| board.liberties(g)),
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
board
|
||||
.group(&Coordinate { column: 0, row: 3 })
|
||||
.map(|g| board.liberties(&g)),
|
||||
.map(|g| board.liberties(g)),
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
board
|
||||
.group(&Coordinate { column: 0, row: 0 })
|
||||
.map(|g| board.liberties(&g)),
|
||||
.map(|g| board.liberties(g)),
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
board
|
||||
.group(&Coordinate { column: 18, row: 9 })
|
||||
.map(|g| board.liberties(&g)),
|
||||
.map(|g| board.liberties(g)),
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
@ -471,7 +469,7 @@ mod test {
|
||||
column: 18,
|
||||
row: 18
|
||||
})
|
||||
.map(|g| board.liberties(&g)),
|
||||
.map(|g| board.liberties(g)),
|
||||
Some(2)
|
||||
);
|
||||
}
|
||||
@ -614,7 +612,7 @@ mod test {
|
||||
for (board, coordinate, group, liberties) in test_cases {
|
||||
assert_eq!(board.group(&coordinate), group.as_ref());
|
||||
assert_eq!(
|
||||
board.group(&coordinate).map(|g| board.liberties(&g)),
|
||||
board.group(&coordinate).map(|g| board.liberties(g)),
|
||||
liberties,
|
||||
"{:?}",
|
||||
coordinate
|
||||
@ -688,11 +686,11 @@ mod test {
|
||||
fn validate_group_comparisons() {
|
||||
{
|
||||
let b1 = Goban::from_coordinates(
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)].into_iter(),
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)],
|
||||
)
|
||||
.unwrap();
|
||||
let b2 = Goban::from_coordinates(
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)].into_iter(),
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -704,16 +702,14 @@ mod test {
|
||||
vec![
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
(Coordinate { column: 8, row: 10 }, Color::White),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
let b2 = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 8, row: 10 }, Color::White),
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -732,8 +728,7 @@ mod test {
|
||||
(Coordinate { column: 10, row: 9 }, Color::Black),
|
||||
(Coordinate { column: 9, row: 8 }, Color::Black),
|
||||
(Coordinate { column: 9, row: 10 }, Color::Black),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -587,8 +587,7 @@ mod test {
|
||||
(Coordinate { column: 17, row: 0 }, Color::White),
|
||||
(Coordinate { column: 17, row: 1 }, Color::White),
|
||||
(Coordinate { column: 18, row: 1 }, Color::White),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
state.current_player = Color::Black;
|
||||
@ -612,8 +611,7 @@ mod test {
|
||||
(Coordinate { column: 10, row: 9 }, Color::Black),
|
||||
(Coordinate { column: 9, row: 8 }, Color::Black),
|
||||
(Coordinate { column: 9, row: 10 }, Color::Black),
|
||||
]
|
||||
.into_iter(),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -132,10 +132,10 @@ impl GameReviewViewModel {
|
||||
// the board state by applying the child.
|
||||
pub fn next_move(&self) {
|
||||
let mut inner = self.inner.write().unwrap();
|
||||
let current_position = inner.current_position.clone();
|
||||
let current_position = inner.current_position;
|
||||
match current_position {
|
||||
Some(current_position) => {
|
||||
let current_id = current_position.clone();
|
||||
let current_id = current_position;
|
||||
let node = inner.game.trees[0].get(current_id).unwrap();
|
||||
if let Some(next_id) = node.first_child().map(|child| child.node_id()) {
|
||||
inner.current_position = Some(next_id);
|
||||
@ -180,7 +180,7 @@ mod test {
|
||||
where
|
||||
F: FnOnce(GameReviewViewModel),
|
||||
{
|
||||
let records = sgf::parse_sgf_file(&Path::new("../../sgf/test_data/branch_test.sgf"))
|
||||
let records = sgf::parse_sgf_file(Path::new("../../sgf/test_data/branch_test.sgf"))
|
||||
.expect("to successfully load the test file");
|
||||
let record = records[0]
|
||||
.as_ref()
|
||||
|
@ -18,7 +18,7 @@ use crate::{CoreApi, ResourceManager};
|
||||
use adw::prelude::*;
|
||||
|
||||
use glib::Propagation;
|
||||
use gtk::{gdk::Key, EventControllerKey};
|
||||
use gtk::EventControllerKey;
|
||||
use otg_core::{
|
||||
settings::{SettingsRequest, SettingsResponse},
|
||||
CoreRequest, CoreResponse, GameReviewViewModel,
|
||||
|
@ -102,14 +102,8 @@ impl GameReview {
|
||||
}
|
||||
}
|
||||
|
||||
match *s.goban.borrow_mut() {
|
||||
Some(ref mut goban) => goban.set_board_state(view.game_view()),
|
||||
None => {}
|
||||
};
|
||||
match *s.review_tree.borrow() {
|
||||
Some(ref tree) => tree.queue_draw(),
|
||||
None => {}
|
||||
}
|
||||
if let Some(ref mut goban) = *s.goban.borrow_mut() { goban.set_board_state(view.game_view()) };
|
||||
if let Some(ref tree) = *s.review_tree.borrow() { tree.queue_draw() }
|
||||
Propagation::Stop
|
||||
}
|
||||
});
|
||||
@ -169,9 +163,6 @@ impl GameReview {
|
||||
*self.review_tree.borrow_mut() = Some(review_tree);
|
||||
}
|
||||
|
||||
fn redraw(&self) {
|
||||
}
|
||||
|
||||
pub fn widget(&self) -> gtk::Widget {
|
||||
self.widget.clone().upcast::<gtk::Widget>()
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ license = "GPL-3.0-only"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-std = "1.13.0"
|
||||
glib = { version = "0.18" }
|
||||
gtk = { version = "0.7", package = "gtk4" }
|
||||
|
@ -66,9 +66,8 @@ impl Screenplay {
|
||||
/// This function currently returns no errors, instead panicing if anything goes wrong.
|
||||
pub fn new(gtk_app: >k::Application, screens: Vec<Screen>) -> Result<Self, Error> {
|
||||
let window = gtk::ApplicationWindow::new(gtk_app);
|
||||
window.show();
|
||||
|
||||
let (sender, receiver) = gtk::glib::MainContext::channel(gtk::glib::Priority::DEFAULT);
|
||||
let (sender, receiver) = async_std::channel::unbounded();
|
||||
|
||||
let layout = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
@ -90,12 +89,16 @@ impl Screenplay {
|
||||
layout.append(&frame);
|
||||
|
||||
listbox.connect_row_activated(move |_, row| {
|
||||
let sender = sender.clone();
|
||||
let row = row.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
match row.index() {
|
||||
-1 => sender.send(Action::Deselect),
|
||||
idx => sender.send(Action::SelectPage(idx as usize)),
|
||||
-1 => sender.send(Action::Deselect).await,
|
||||
idx => sender.send(Action::SelectPage(idx as usize)).await,
|
||||
}
|
||||
.unwrap()
|
||||
});
|
||||
});
|
||||
|
||||
screens.iter().for_each(|Screen { title, .. }| {
|
||||
listbox.append(
|
||||
@ -108,8 +111,14 @@ impl Screenplay {
|
||||
let storybook = Self { frame, screens };
|
||||
|
||||
{
|
||||
glib::spawn_future_local({
|
||||
let mut storybook = storybook.clone();
|
||||
receiver.attach(None, move |message| storybook.process_action(message));
|
||||
async move {
|
||||
while let Ok(msg) = receiver.recv().await {
|
||||
storybook.process_action(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(storybook)
|
||||
|
@ -10,7 +10,7 @@ use nom::{
|
||||
IResult, Parser,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt::Write, num::ParseIntError, time::Duration};
|
||||
use std::{fmt::Display, num::ParseIntError, time::Duration};
|
||||
|
||||
impl From<ParseSizeError> for Error {
|
||||
fn from(_: ParseSizeError) -> Self {
|
||||
@ -142,9 +142,9 @@ impl From<&GameType> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for GameType {
|
||||
fn to_string(&self) -> String {
|
||||
String::from(self)
|
||||
impl Display for GameType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", String::from(self))
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,12 +189,15 @@ pub struct Tree {
|
||||
pub root: Node,
|
||||
}
|
||||
|
||||
impl ToString for Tree {
|
||||
fn to_string(&self) -> String {
|
||||
format!("({})", self.root.to_string())
|
||||
impl Display for Tree {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "({})", self.root)
|
||||
}
|
||||
}
|
||||
|
||||
struct Properties<'a>(&'a Vec<Property>);
|
||||
struct Nodes<'a>(&'a Vec<Node>);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Node {
|
||||
pub properties: Vec<Property>,
|
||||
@ -264,8 +267,12 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Node {
|
||||
fn to_string(&self) -> String {
|
||||
impl Display for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, ";{}", Properties(&self.properties))?;
|
||||
write!(f, "{}", Nodes(&self.next))?;
|
||||
Ok(())
|
||||
/*
|
||||
let props = self
|
||||
.properties
|
||||
.iter()
|
||||
@ -281,11 +288,36 @@ impl ToString for Node {
|
||||
} else {
|
||||
self.next
|
||||
.iter()
|
||||
.map(|node| format!("({})", node.to_string()))
|
||||
.map(|node| write!(f, "({})", node.to_string()))
|
||||
.collect::<Vec<String>>()
|
||||
.join("")
|
||||
};
|
||||
format!(";{}{}", props, next)
|
||||
write!(f, ";{}{}", props, next)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Properties<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for property in self.0.iter() {
|
||||
write!(f, "{}", property)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Nodes<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.0.len() == 1 {
|
||||
for node in self.0.iter() {
|
||||
write!(f, "{}", node)?;
|
||||
}
|
||||
} else {
|
||||
for node in self.0.iter() {
|
||||
write!(f, "({})", node)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -460,95 +492,96 @@ pub struct UnknownProperty {
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl ToString for Property {
|
||||
fn to_string(&self) -> String {
|
||||
impl Display for Property {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Property::Move((color, Move::Move(mv))) => {
|
||||
format!("{}[{}]", color.abbreviation(), mv)
|
||||
write!(f, "{}[{}]", color.abbreviation(), mv)
|
||||
}
|
||||
Property::Move((color, Move::Pass)) => {
|
||||
format!("{}[]", color.abbreviation())
|
||||
write!(f, "{}[]", color.abbreviation())
|
||||
}
|
||||
Property::TimeLeft((color, time)) => {
|
||||
format!("{}[{}]", color.abbreviation(), time.as_secs())
|
||||
write!(f, "{}[{}]", color.abbreviation(), time.as_secs())
|
||||
}
|
||||
Property::Comment(value) => format!("C[{}]", value),
|
||||
Property::Annotation(Annotation::BadMove) => "BM[]".to_owned(),
|
||||
Property::Annotation(Annotation::DoubtfulMove) => "DO[]".to_owned(),
|
||||
Property::Annotation(Annotation::InterestingMove) => "IT[]".to_owned(),
|
||||
Property::Annotation(Annotation::Tesuji) => "TE[]".to_owned(),
|
||||
Property::Application(app) => format!("AP[{}]", app),
|
||||
Property::Charset(set) => format!("CA[{}]", set),
|
||||
Property::FileFormat(ff) => format!("FF[{}]", ff),
|
||||
Property::GameType(gt) => format!("GM[{}]", gt.to_string()),
|
||||
Property::Comment(value) => write!(f, "C[{}]", value),
|
||||
Property::Annotation(Annotation::BadMove) => write!(f, "BM[]"),
|
||||
Property::Annotation(Annotation::DoubtfulMove) => write!(f, "DO[]"),
|
||||
Property::Annotation(Annotation::InterestingMove) => write!(f, "IT[]"),
|
||||
Property::Annotation(Annotation::Tesuji) => write!(f, "TE[]"),
|
||||
Property::Application(app) => write!(f, "AP[{}]", app),
|
||||
Property::Charset(set) => write!(f, "CA[{}]", set),
|
||||
Property::FileFormat(ff) => write!(f, "FF[{}]", ff),
|
||||
Property::GameType(gt) => write!(f, "GM[{}]", gt),
|
||||
Property::VariationDisplay => unimplemented!(),
|
||||
Property::BoardSize(Size { width, height }) => {
|
||||
if width == height {
|
||||
format!("SZ[{}]", width)
|
||||
write!(f, "SZ[{}]", width)
|
||||
} else {
|
||||
format!("SZ[{}:{}]", width, height)
|
||||
write!(f, "SZ[{}:{}]", width, height)
|
||||
}
|
||||
}
|
||||
Property::SetupBlackStones(positions) => {
|
||||
format!("AB[{}]", positions.compressed_list(),)
|
||||
write!(f, "AB[{}]", positions.compressed_list(),)
|
||||
}
|
||||
Property::ClearStones(positions) => {
|
||||
format!("AE[{}]", positions.compressed_list(),)
|
||||
write!(f, "AE[{}]", positions.compressed_list(),)
|
||||
}
|
||||
Property::SetupWhiteStones(positions) => {
|
||||
format!("AW[{}]", positions.compressed_list(),)
|
||||
write!(f, "AW[{}]", positions.compressed_list(),)
|
||||
}
|
||||
Property::NextPlayer(color) => format!("PL[{}]", color.abbreviation()),
|
||||
Property::Evaluation(Evaluation::Even) => "DM[]".to_owned(),
|
||||
Property::Evaluation(Evaluation::GoodForBlack) => "GB[]".to_owned(),
|
||||
Property::Evaluation(Evaluation::GoodForWhite) => "GW[]".to_owned(),
|
||||
Property::Evaluation(Evaluation::Unclear) => "UC[]".to_owned(),
|
||||
Property::Hotspot => "HO[]".to_owned(),
|
||||
Property::Value(value) => format!("V[{}]", value),
|
||||
Property::Annotator(value) => format!("AN[{}]", value),
|
||||
Property::BlackRank(value) => format!("BR[{}]", value),
|
||||
Property::BlackTeam(value) => format!("BT[{}]", value),
|
||||
Property::Copyright(value) => format!("CP[{}]", value),
|
||||
Property::NextPlayer(color) => write!(f, "PL[{}]", color.abbreviation()),
|
||||
Property::Evaluation(Evaluation::Even) => write!(f, "DM[]"),
|
||||
Property::Evaluation(Evaluation::GoodForBlack) => write!(f, "GB[]"),
|
||||
Property::Evaluation(Evaluation::GoodForWhite) => write!(f, "GW[]"),
|
||||
Property::Evaluation(Evaluation::Unclear) => write!(f, "UC[]"),
|
||||
Property::Hotspot => write!(f, "HO[]"),
|
||||
Property::Value(value) => write!(f, "V[{}]", value),
|
||||
Property::Annotator(value) => write!(f, "AN[{}]", value),
|
||||
Property::BlackRank(value) => write!(f, "BR[{}]", value),
|
||||
Property::BlackTeam(value) => write!(f, "BT[{}]", value),
|
||||
Property::Copyright(value) => write!(f, "CP[{}]", value),
|
||||
Property::EventDates(_) => unimplemented!(),
|
||||
Property::EventName(value) => format!("EV[{}]", value),
|
||||
Property::GameName(value) => format!("GN[{}]", value),
|
||||
Property::ExtraGameInformation(value) => format!("GC[{}]", value),
|
||||
Property::GameOpening(value) => format!("ON[{}]", value),
|
||||
Property::Overtime(value) => format!("OT[{}]", value),
|
||||
Property::BlackPlayer(value) => format!("PB[{}]", value),
|
||||
Property::GameLocation(value) => format!("PC[{}]", value),
|
||||
Property::WhitePlayer(value) => format!("PW[{}]", value),
|
||||
Property::EventName(value) => write!(f, "EV[{}]", value),
|
||||
Property::GameName(value) => write!(f, "GN[{}]", value),
|
||||
Property::ExtraGameInformation(value) => write!(f, "GC[{}]", value),
|
||||
Property::GameOpening(value) => write!(f, "ON[{}]", value),
|
||||
Property::Overtime(value) => write!(f, "OT[{}]", value),
|
||||
Property::BlackPlayer(value) => write!(f, "PB[{}]", value),
|
||||
Property::GameLocation(value) => write!(f, "PC[{}]", value),
|
||||
Property::WhitePlayer(value) => write!(f, "PW[{}]", value),
|
||||
Property::Result(_) => unimplemented!(),
|
||||
Property::Round(value) => format!("RO[{}]", value),
|
||||
Property::Ruleset(value) => format!("RU[{}]", value),
|
||||
Property::Source(value) => format!("SO[{}]", value),
|
||||
Property::TimeLimit(value) => format!("TM[{}]", value.as_secs()),
|
||||
Property::User(value) => format!("US[{}]", value),
|
||||
Property::WhiteRank(value) => format!("WR[{}]", value),
|
||||
Property::WhiteTeam(value) => format!("WT[{}]", value),
|
||||
Property::Round(value) => write!(f, "RO[{}]", value),
|
||||
Property::Ruleset(value) => write!(f, "RU[{}]", value),
|
||||
Property::Source(value) => write!(f, "SO[{}]", value),
|
||||
Property::TimeLimit(value) => write!(f, "TM[{}]", value.as_secs()),
|
||||
Property::User(value) => write!(f, "US[{}]", value),
|
||||
Property::WhiteRank(value) => write!(f, "WR[{}]", value),
|
||||
Property::WhiteTeam(value) => write!(f, "WT[{}]", value),
|
||||
Property::Territory(Color::White, positions) => {
|
||||
positions
|
||||
.iter()
|
||||
.fold("TW".to_owned(), |mut output, Position(p)| {
|
||||
let _ = write!(output, "{}", p);
|
||||
output
|
||||
})
|
||||
write!(f, "TW[{}]", Positions(positions))
|
||||
}
|
||||
Property::Territory(Color::Black, positions) => {
|
||||
positions
|
||||
.iter()
|
||||
.fold("TB".to_owned(), |mut output, Position(p)| {
|
||||
let _ = write!(output, "{}", p);
|
||||
output
|
||||
})
|
||||
write!(f, "TB[{}]", Positions(positions))
|
||||
}
|
||||
Property::Unknown(UnknownProperty { ident, value }) => {
|
||||
format!("{}[{}]", ident, value)
|
||||
write!(f, "{}[{}]", ident, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Positions<'a>(&'a Vec<Position>);
|
||||
|
||||
impl Display for Positions<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for Position(p) in self.0.iter() {
|
||||
write!(f, "{}", p)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_collection<'a, E: nom::error::ParseError<&'a str>>(
|
||||
input: &'a str,
|
||||
) -> IResult<&'a str, Vec<Tree>, E> {
|
||||
|
@ -53,6 +53,7 @@ pub enum Error {
|
||||
// InvalidField,
|
||||
// InvalidBoardSize,
|
||||
Incomplete,
|
||||
#[allow(dead_code)]
|
||||
InvalidSgf(VerboseNomError),
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chrono::{DateTime, FixedOffset, NaiveDate, TimeZone};
|
||||
use chrono_tz::{
|
||||
America::{New_York, Phoenix},
|
||||
Tz,
|
||||
US::Mountain,
|
||||
};
|
||||
use chrono_tz::America::{New_York, Phoenix};
|
||||
|
||||
#[test]
|
||||
fn it_saves_with_offset() {
|
||||
@ -37,7 +33,7 @@ mod tests {
|
||||
date.with_timezone(&New_York),
|
||||
FixedOffset::west_opt(4 * 60 * 60)
|
||||
.unwrap()
|
||||
.with_ymd_and_hms(2023, 10, 14, 03, 0, 0)
|
||||
.with_ymd_and_hms(2023, 10, 14, 3, 0, 0)
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -62,7 +62,7 @@ impl<T> Tree<T> {
|
||||
// Do a depth-first-search in order to get the path to a node. Start with a naive recursive
|
||||
// implementation, then switch to a stack-based implementation in order to avoid exceeding the
|
||||
// stack.
|
||||
pub fn path_to<F>(&self, f: F) -> Vec<Node<T>>
|
||||
pub fn path_to<F>(&self, _f: F) -> Vec<Node<T>>
|
||||
where
|
||||
F: FnOnce(&T) -> bool + Copy,
|
||||
{
|
||||
@ -206,17 +206,20 @@ mod tests {
|
||||
assert!(tree2.find_bfs(|val| *val == "17").is_some());
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn path_to_on_empty_tree_returns_empty() {
|
||||
let tree: Tree<&str> = Tree::default();
|
||||
|
||||
assert_eq!(tree.path_to(|val| *val == "i"), vec![]);
|
||||
}
|
||||
*/
|
||||
|
||||
// A
|
||||
// B G H
|
||||
// C I
|
||||
// D E F
|
||||
/*
|
||||
#[test]
|
||||
fn it_can_find_a_path_to_a_node() {
|
||||
let (tree, a) = Tree::new("A");
|
||||
@ -232,4 +235,5 @@ mod tests {
|
||||
assert_eq!(tree.path_to(|val| *val == "z"), vec![]);
|
||||
assert_eq!(tree.path_to(|val| *val == "i"), vec![a, h, i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ edition = "2021"
|
||||
async-std = { version = "1.13.0" }
|
||||
async-trait = { version = "0.1.83" }
|
||||
authdb = { path = "../../authdb/" }
|
||||
axum = { version = "0.7.9" }
|
||||
axum = { version = "0.7.9", features = [ "macros" ] }
|
||||
futures = { version = "0.3.31" }
|
||||
include_dir = { version = "0.7.4" }
|
||||
lazy_static = { version = "1.5.0" }
|
||||
@ -24,6 +24,7 @@ serde_json = { version = "*" }
|
||||
thiserror = { version = "2.0.3" }
|
||||
tokio = { version = "1", features = [ "full" ] }
|
||||
tokio-stream = { version = "0.1.16" }
|
||||
tower-http = { version = "0.6.2", features = ["cors"] }
|
||||
typeshare = { version = "1.0.4" }
|
||||
urlencoding = { version = "2.1.3" }
|
||||
uuid = { version = "1.11.0", features = ["v4"] }
|
||||
|
@ -139,14 +139,14 @@ pub mod mocks {
|
||||
}
|
||||
|
||||
impl Assets for MemoryAssets {
|
||||
fn assets<'a>(&'a self) -> AssetIter<'a> {
|
||||
fn assets(&self) -> AssetIter<'_> {
|
||||
AssetIter(self.asset_paths.iter())
|
||||
}
|
||||
|
||||
fn get(&self, asset_id: AssetId) -> Result<(Mime, Vec<u8>), Error> {
|
||||
match (self.asset_paths.get(&asset_id), self.assets.get(&asset_id)) {
|
||||
(Some(path), Some(data)) => {
|
||||
let mime = mime_guess::from_path(&path).first().unwrap();
|
||||
let mime = mime_guess::from_path(path).first().unwrap();
|
||||
Ok((mime, data.to_vec()))
|
||||
}
|
||||
_ => Err(Error::NotFound),
|
||||
|
@ -10,7 +10,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
asset_db::{self, AssetId, Assets},
|
||||
database::{CharacterId, Database, GameId, SessionId, UserId}, types::{AppError, FatalError, Game, GameOverview, Message, Rgb, Tabletop, User, UserProfile},
|
||||
database::{CharacterId, Database, GameId, SessionId, UserId}, types::{AppError, FatalError, GameOverview, Message, Rgb, Tabletop, User, UserProfile},
|
||||
};
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR: Rgb = Rgb {
|
||||
@ -225,7 +225,7 @@ impl Core {
|
||||
&self,
|
||||
id: CharacterId,
|
||||
) -> ResultExt<Option<serde_json::Value>, AppError, FatalError> {
|
||||
let mut state = self.0.write().await;
|
||||
let state = self.0.write().await;
|
||||
let cr = state.db.character(&id).await;
|
||||
match cr {
|
||||
Ok(Some(row)) => ok(Some(row.data)),
|
||||
|
@ -195,7 +195,7 @@ mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
const SOREN: &'static str = r#"{ "type_": "Candela", "name": "Soren Jensen", "pronouns": "he/him", "circle": "Circle of the Bluest Sky", "style": "dapper gentleman", "catalyst": "a cursed book", "question": "What were the contents of that book?", "nerve": { "type_": "nerve", "drives": { "current": 1, "max": 2 }, "resistances": { "current": 0, "max": 3 }, "move": { "gilded": false, "score": 2 }, "strike": { "gilded": false, "score": 1 }, "control": { "gilded": true, "score": 0 } }, "cunning": { "type_": "cunning", "drives": { "current": 1, "max": 1 }, "resistances": { "current": 0, "max": 3 }, "sway": { "gilded": false, "score": 0 }, "read": { "gilded": false, "score": 0 }, "hide": { "gilded": false, "score": 0 } }, "intuition": { "type_": "intuition", "drives": { "current": 0, "max": 0 }, "resistances": { "current": 0, "max": 3 }, "survey": { "gilded": false, "score": 0 }, "focus": { "gilded": false, "score": 0 }, "sense": { "gilded": false, "score": 0 } }, "role": "Slink", "role_abilities": [ "Scout: If you have time to observe a location, you can spend 1 Intuition to ask a question: What do I notice here that others do not see? What in this place might be of use to us? What path should we follow?" ], "specialty": "Detective", "specialty_abilities": [ "Mind Palace: When you want to figure out how two clues might relate or what path they should point you towards, burn 1 Intution resistance. The GM will give you the information you have deduced." ] }"#;
|
||||
const SOREN: &str = r#"{ "type_": "Candela", "name": "Soren Jensen", "pronouns": "he/him", "circle": "Circle of the Bluest Sky", "style": "dapper gentleman", "catalyst": "a cursed book", "question": "What were the contents of that book?", "nerve": { "type_": "nerve", "drives": { "current": 1, "max": 2 }, "resistances": { "current": 0, "max": 3 }, "move": { "gilded": false, "score": 2 }, "strike": { "gilded": false, "score": 1 }, "control": { "gilded": true, "score": 0 } }, "cunning": { "type_": "cunning", "drives": { "current": 1, "max": 1 }, "resistances": { "current": 0, "max": 3 }, "sway": { "gilded": false, "score": 0 }, "read": { "gilded": false, "score": 0 }, "hide": { "gilded": false, "score": 0 } }, "intuition": { "type_": "intuition", "drives": { "current": 0, "max": 0 }, "resistances": { "current": 0, "max": 3 }, "survey": { "gilded": false, "score": 0 }, "focus": { "gilded": false, "score": 0 }, "sense": { "gilded": false, "score": 0 } }, "role": "Slink", "role_abilities": [ "Scout: If you have time to observe a location, you can spend 1 Intuition to ask a question: What do I notice here that others do not see? What in this place might be of use to us? What path should we follow?" ], "specialty": "Detective", "specialty_abilities": [ "Mind Palace: When you want to figure out how two clues might relate or what path they should point you towards, burn 1 Intution resistance. The GM will give you the information you have deduced." ] }"#;
|
||||
|
||||
fn setup_db() -> (DiskDb, GameId) {
|
||||
let no_path: Option<PathBuf> = None;
|
||||
@ -221,7 +221,7 @@ mod test {
|
||||
#[tokio::test]
|
||||
async fn it_can_retrieve_a_character_through_conn() {
|
||||
let memory_db: Option<PathBuf> = None;
|
||||
let mut conn = DbConn::new(memory_db);
|
||||
let conn = DbConn::new(memory_db);
|
||||
|
||||
assert_matches!(conn.character(&CharacterId::from("1")).await, Ok(None));
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ use std::fmt;
|
||||
|
||||
use rusqlite::types::{FromSql, FromSqlResult, ValueRef};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[typeshare]
|
||||
pub struct UserId(String);
|
||||
|
||||
impl UserId {
|
||||
@ -47,6 +49,7 @@ impl fmt::Display for UserId {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[typeshare]
|
||||
pub struct SessionId(String);
|
||||
|
||||
impl SessionId {
|
||||
@ -87,6 +90,7 @@ impl fmt::Display for SessionId {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[typeshare]
|
||||
pub struct GameId(String);
|
||||
|
||||
impl GameId {
|
||||
@ -121,6 +125,7 @@ impl FromSql for GameId {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[typeshare]
|
||||
pub struct CharacterId(String);
|
||||
|
||||
impl CharacterId {
|
||||
|
@ -1,13 +1,15 @@
|
||||
use axum::{http::{HeaderMap, StatusCode}, Json};
|
||||
use axum::http::HeaderMap;
|
||||
use result_extended::ResultExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{database::GameId, core::Core};
|
||||
use crate::{
|
||||
core::Core,
|
||||
database::GameId,
|
||||
types::{AppError, FatalError},
|
||||
};
|
||||
|
||||
use super::auth_required;
|
||||
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct CreateGameRequest {
|
||||
pub game_type: String,
|
||||
@ -18,16 +20,10 @@ pub async fn create_game(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
req: CreateGameRequest,
|
||||
) -> (StatusCode, Json<Option<GameId>>) {
|
||||
println!("create game handler");
|
||||
) -> ResultExt<GameId, AppError, FatalError> {
|
||||
auth_required(core.clone(), headers, |user| async move {
|
||||
let game = core.create_game(&user.id, &req.game_type, &req.game_name).await;
|
||||
println!("create_game completed: {:?}", game);
|
||||
match game {
|
||||
ResultExt::Ok(game_id) => (StatusCode::OK, Json(Some(game_id))),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
||||
core.create_game(&user.id, &req.game_type, &req.game_name)
|
||||
.await
|
||||
})
|
||||
.await
|
||||
}
|
||||
}).await
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,47 @@
|
||||
mod game_management;
|
||||
mod user_management;
|
||||
use axum::{http::StatusCode, Json};
|
||||
use futures::Future;
|
||||
pub use game_management::*;
|
||||
pub use user_management::*;
|
||||
|
||||
use result_extended::ResultExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::core::Core;
|
||||
use crate::{
|
||||
core::Core,
|
||||
types::{AppError, FatalError},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct HealthCheck {
|
||||
pub ok: bool,
|
||||
}
|
||||
|
||||
pub async fn wrap_handler<F, A, Fut>(f: F) -> (StatusCode, Json<Option<A>>)
|
||||
where
|
||||
F: FnOnce() -> Fut,
|
||||
Fut: Future<Output = ResultExt<A, AppError, FatalError>>,
|
||||
{
|
||||
match f().await {
|
||||
ResultExt::Ok(val) => (StatusCode::OK, Json(Some(val))),
|
||||
ResultExt::Err(AppError::BadRequest) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Err(AppError::CouldNotCreateObject) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Err(AppError::NotFound(_)) => (StatusCode::NOT_FOUND, Json(None)),
|
||||
ResultExt::Err(AppError::Inaccessible(_)) => (StatusCode::NOT_FOUND, Json(None)),
|
||||
ResultExt::Err(AppError::PermissionDenied) => (StatusCode::FORBIDDEN, Json(None)),
|
||||
ResultExt::Err(AppError::AuthFailed) => (StatusCode::UNAUTHORIZED, Json(None)),
|
||||
ResultExt::Err(AppError::JsonError(_)) => (StatusCode::INTERNAL_SERVER_ERROR, Json(None)),
|
||||
ResultExt::Err(AppError::UnexpectedError(_)) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(None))
|
||||
}
|
||||
ResultExt::Err(AppError::UsernameUnavailable) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(err) => {
|
||||
panic!("The server encountered a fatal error: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn healthcheck(core: Core) -> Vec<u8> {
|
||||
match core.status().await {
|
||||
ResultExt::Ok(s) => serde_json::to_vec(&HealthCheck {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use axum::{
|
||||
http::{HeaderMap, StatusCode},
|
||||
http::HeaderMap,
|
||||
Json,
|
||||
};
|
||||
use futures::Future;
|
||||
use result_extended::{error, ok, ResultExt};
|
||||
use result_extended::{error, ok, return_error, ResultExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
@ -58,16 +58,14 @@ pub async fn auth_required<F, A, Fut>(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
f: F,
|
||||
) -> (StatusCode, Json<Option<A>>)
|
||||
) -> ResultExt<A, AppError, FatalError>
|
||||
where
|
||||
F: FnOnce(User) -> Fut,
|
||||
Fut: Future<Output = (StatusCode, Json<Option<A>>)>,
|
||||
Fut: Future<Output = ResultExt<A, AppError, FatalError>>,
|
||||
{
|
||||
match check_session(&core, headers).await {
|
||||
ResultExt::Ok(Some(user)) => f(user).await,
|
||||
ResultExt::Ok(None) => (StatusCode::UNAUTHORIZED, Json(None)),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(err) => panic!("{}", err),
|
||||
match return_error!(check_session(&core, headers).await) {
|
||||
Some(user) => f(user).await,
|
||||
None => error(AppError::AuthFailed),
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,94 +73,64 @@ pub async fn admin_required<F, A, Fut>(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
f: F,
|
||||
) -> (StatusCode, Json<Option<A>>)
|
||||
) -> ResultExt<A, AppError, FatalError>
|
||||
where
|
||||
F: FnOnce(User) -> Fut,
|
||||
Fut: Future<Output = (StatusCode, Json<Option<A>>)>,
|
||||
Fut: Future<Output = ResultExt<A, AppError, FatalError>>,
|
||||
{
|
||||
match check_session(&core, headers).await {
|
||||
ResultExt::Ok(Some(user)) => {
|
||||
match return_error!(check_session(&core, headers).await) {
|
||||
Some(user) => {
|
||||
if user.admin {
|
||||
f(user).await
|
||||
} else {
|
||||
(StatusCode::FORBIDDEN, Json(None))
|
||||
error(AppError::PermissionDenied)
|
||||
}
|
||||
}
|
||||
ResultExt::Ok(None) => (StatusCode::UNAUTHORIZED, Json(None)),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(err) => panic!("{}", err),
|
||||
None => error(AppError::AuthFailed),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_password(
|
||||
core: Core,
|
||||
req: Json<AuthRequest>,
|
||||
) -> (StatusCode, Json<Option<SessionId>>) {
|
||||
) -> ResultExt<SessionId, AppError, FatalError> {
|
||||
let Json(AuthRequest { username, password }) = req;
|
||||
match core.auth(&username, &password).await {
|
||||
ResultExt::Ok(session_id) => (StatusCode::OK, Json(Some(session_id))),
|
||||
ResultExt::Err(_err) => (StatusCode::UNAUTHORIZED, Json(None)),
|
||||
ResultExt::Fatal(err) => panic!("Fatal: {}", err),
|
||||
}
|
||||
core.auth(&username, &password).await
|
||||
}
|
||||
|
||||
pub async fn get_user(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
user_id: Option<UserId>,
|
||||
) -> (StatusCode, Json<Option<UserProfile>>) {
|
||||
) -> ResultExt<Option<UserProfile>, AppError, FatalError> {
|
||||
auth_required(core.clone(), headers, |user| async move {
|
||||
match user_id {
|
||||
Some(user_id) => match core.user(user_id).await {
|
||||
ResultExt::Ok(Some(user)) => (StatusCode::OK, Json(Some(user))),
|
||||
ResultExt::Ok(None) => (StatusCode::NOT_FOUND, Json(None)),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(err) => panic!("{}", err),
|
||||
},
|
||||
None => (
|
||||
StatusCode::OK,
|
||||
Json(Some(UserProfile {
|
||||
id: UserId::from(user.id),
|
||||
name: user.name,
|
||||
is_admin: user.admin,
|
||||
games: vec![],
|
||||
})),
|
||||
),
|
||||
Some(user_id) => core.user(user_id).await,
|
||||
None => core.user(user.id).await,
|
||||
}
|
||||
})
|
||||
.await
|
||||
}).await
|
||||
}
|
||||
|
||||
pub async fn create_user(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
req: CreateUserRequest,
|
||||
) -> (StatusCode, Json<Option<()>>) {
|
||||
) -> ResultExt<UserId, AppError, FatalError> {
|
||||
admin_required(core.clone(), headers, |_admin| async {
|
||||
match core.create_user(&req.username).await {
|
||||
ResultExt::Ok(_) => (StatusCode::OK, Json(None)),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
||||
}
|
||||
})
|
||||
.await
|
||||
core.create_user(&req.username).await
|
||||
}).await
|
||||
}
|
||||
|
||||
pub async fn set_password(
|
||||
core: Core,
|
||||
headers: HeaderMap,
|
||||
req: SetPasswordRequest,
|
||||
) -> (StatusCode, Json<Option<()>>) {
|
||||
) -> ResultExt<(), AppError, FatalError> {
|
||||
auth_required(core.clone(), headers, |user| async {
|
||||
if req.password_1 == req.password_2 {
|
||||
match core.set_password(user.id, req.password_1).await {
|
||||
ResultExt::Ok(_) => (StatusCode::OK, Json(None)),
|
||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
||||
}
|
||||
core.set_password(user.id, req.password_1).await
|
||||
} else {
|
||||
(StatusCode::BAD_REQUEST, Json(None))
|
||||
error(AppError::BadRequest)
|
||||
}
|
||||
})
|
||||
.await
|
||||
}).await
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::HeaderMap,
|
||||
http::{header::{AUTHORIZATION, CONTENT_TYPE}, HeaderMap, Method},
|
||||
routing::{get, post, put},
|
||||
Json, Router,
|
||||
};
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
|
||||
use crate::{
|
||||
core::Core,
|
||||
database::UserId,
|
||||
handlers::{
|
||||
check_password, create_game, create_user, get_user, healthcheck, set_password, AuthRequest,
|
||||
CreateGameRequest, CreateUserRequest, SetPasswordRequest,
|
||||
check_password, create_game, create_user, get_user, healthcheck, set_password,
|
||||
wrap_handler, AuthRequest, CreateGameRequest, CreateUserRequest, SetPasswordRequest,
|
||||
},
|
||||
};
|
||||
|
||||
@ -21,27 +22,44 @@ pub fn routes(core: Core) -> Router {
|
||||
get({
|
||||
let core = core.clone();
|
||||
move || healthcheck(core)
|
||||
}),
|
||||
})
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_methods([Method::GET])
|
||||
.allow_origin(Any),
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/api/v1/auth",
|
||||
post({
|
||||
let core = core.clone();
|
||||
move |req: Json<AuthRequest>| check_password(core, req)
|
||||
}),
|
||||
move |req: Json<AuthRequest>| wrap_handler(|| check_password(core, req))
|
||||
})
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_methods([Method::POST])
|
||||
.allow_headers([CONTENT_TYPE])
|
||||
.allow_origin(Any),
|
||||
),
|
||||
)
|
||||
.route(
|
||||
// By default, just get the self user.
|
||||
"/api/v1/user",
|
||||
get({
|
||||
let core = core.clone();
|
||||
move |headers: HeaderMap| get_user(core, headers, None)
|
||||
move |headers: HeaderMap| wrap_handler(|| get_user(core, headers, None))
|
||||
})
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_methods([Method::GET])
|
||||
.allow_headers([AUTHORIZATION])
|
||||
.allow_origin(Any),
|
||||
)
|
||||
.put({
|
||||
let core = core.clone();
|
||||
move |headers: HeaderMap, req: Json<CreateUserRequest>| {
|
||||
let Json(req) = req;
|
||||
create_user(core, headers, req)
|
||||
wrap_handler(|| create_user(core, headers, req))
|
||||
}
|
||||
}),
|
||||
)
|
||||
@ -51,7 +69,7 @@ pub fn routes(core: Core) -> Router {
|
||||
let core = core.clone();
|
||||
move |headers: HeaderMap, req: Json<SetPasswordRequest>| {
|
||||
let Json(req) = req;
|
||||
set_password(core, headers, req)
|
||||
wrap_handler(|| set_password(core, headers, req))
|
||||
}
|
||||
}),
|
||||
)
|
||||
@ -61,7 +79,7 @@ pub fn routes(core: Core) -> Router {
|
||||
let core = core.clone();
|
||||
move |user_id: Path<UserId>, headers: HeaderMap| {
|
||||
let Path(user_id) = user_id;
|
||||
get_user(core, headers, Some(user_id))
|
||||
wrap_handler(|| get_user(core, headers, Some(user_id)))
|
||||
}
|
||||
}),
|
||||
)
|
||||
@ -71,7 +89,7 @@ pub fn routes(core: Core) -> Router {
|
||||
let core = core.clone();
|
||||
move |headers: HeaderMap, req: Json<CreateGameRequest>| {
|
||||
let Json(req) = req;
|
||||
create_game(core, headers, req)
|
||||
wrap_handler(|| create_game(core, headers, req))
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
@ -1,64 +1,64 @@
|
||||
import React, { PropsWithChildren, useContext, useEffect, useState } from 'react';
|
||||
import './App.css';
|
||||
import { Client } from './client';
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||
import { DesignPage } from './views/Design/Design';
|
||||
import { GmView } from './views/GmView/GmView';
|
||||
import { WebsocketProvider } from './components/WebsocketProvider';
|
||||
import { PlayerView } from './views/PlayerView/PlayerView';
|
||||
import { Admin } from './views/Admin/Admin';
|
||||
import Candela from './plugins/Candela';
|
||||
import { Authentication } from './views/Authentication/Authentication';
|
||||
import { StateContext, StateProvider } from './providers/StateProvider/StateProvider';
|
||||
import React, { PropsWithChildren, useContext, useEffect, useState } from 'react'
|
||||
import './App.css'
|
||||
import { Client } from './client'
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
|
||||
import { DesignPage } from './views/Design/Design'
|
||||
import { Admin } from './views/Admin/Admin'
|
||||
import Candela from './plugins/Candela'
|
||||
import { Authentication } from './views/Authentication/Authentication'
|
||||
import { StateContext, StateProvider } from './providers/StateProvider/StateProvider'
|
||||
import { MainView } from './views'
|
||||
|
||||
const TEST_CHARSHEET_UUID = "12df9c09-1f2f-4147-8eda-a97bd2a7a803";
|
||||
const TEST_CHARSHEET_UUID = "12df9c09-1f2f-4147-8eda-a97bd2a7a803"
|
||||
|
||||
interface AppProps {
|
||||
client: Client;
|
||||
client: Client
|
||||
}
|
||||
|
||||
const CandelaCharsheet = ({ client }: { client: Client }) => {
|
||||
let [sheet, setSheet] = useState(undefined);
|
||||
let [sheet, setSheet] = useState(undefined)
|
||||
useEffect(
|
||||
() => { client.charsheet(TEST_CHARSHEET_UUID).then((c) => setSheet(c)); },
|
||||
() => { client.charsheet(TEST_CHARSHEET_UUID).then((c) => setSheet(c)) },
|
||||
[client, setSheet]
|
||||
);
|
||||
)
|
||||
|
||||
return sheet ? <Candela.CharsheetElement sheet={sheet} /> : <div> </div>
|
||||
}
|
||||
|
||||
interface AuthedViewProps {
|
||||
client: Client;
|
||||
client: Client
|
||||
}
|
||||
|
||||
const AuthedView = ({ client, children }: PropsWithChildren<AuthedViewProps>) => {
|
||||
const [state, manager] = useContext(StateContext);
|
||||
const [state, manager] = useContext(StateContext)
|
||||
return (
|
||||
<Authentication onAdminPassword={(password) => {
|
||||
manager.setAdminPassword(password);
|
||||
manager.setAdminPassword(password)
|
||||
}} onAuth={(username, password) => manager.auth(username, password)}>
|
||||
{children}
|
||||
</Authentication>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const App = ({ client }: AppProps) => {
|
||||
console.log("rendering app");
|
||||
const [websocketUrl, setWebsocketUrl] = useState<string | undefined>(undefined);
|
||||
console.log("rendering app")
|
||||
const [websocketUrl, setWebsocketUrl] = useState<string | undefined>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
client.registerWebsocket().then((url) => setWebsocketUrl(url))
|
||||
}, [client]);
|
||||
// useEffect(() => {
|
||||
// client.registerWebsocket().then((url) => setWebsocketUrl(url))
|
||||
// }, [client])
|
||||
|
||||
let router =
|
||||
createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <StateProvider client={client}><AuthedView client={client}> <PlayerView client={client} /> </AuthedView> </StateProvider>
|
||||
},
|
||||
{
|
||||
path: "/gm",
|
||||
element: websocketUrl ? <WebsocketProvider websocketUrl={websocketUrl}> <GmView client={client} /> </WebsocketProvider> : <div> </div>
|
||||
element: (
|
||||
<StateProvider client={client}>
|
||||
<AuthedView client={client}>
|
||||
<MainView client={client} />
|
||||
</AuthedView>
|
||||
</StateProvider>
|
||||
)
|
||||
},
|
||||
{
|
||||
path: "/admin",
|
||||
@ -72,12 +72,12 @@ const App = ({ client }: AppProps) => {
|
||||
path: "/design",
|
||||
element: <DesignPage />
|
||||
}
|
||||
]);
|
||||
])
|
||||
return (
|
||||
<div className="App">
|
||||
<RouterProvider router={router} />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { SessionId, UserId, UserProfile } from "visions-types";
|
||||
|
||||
export type PlayingField = {
|
||||
backgroundImage: string;
|
||||
}
|
||||
|
||||
export class Client {
|
||||
private base: URL;
|
||||
private sessionId: string | undefined;
|
||||
|
||||
constructor() {
|
||||
this.base = new URL("http://localhost:8001");
|
||||
@ -64,15 +67,35 @@ export class Client {
|
||||
return fetch(url, { method: 'PUT', headers: [['Content-Type', 'application/json']], body: JSON.stringify(password) });
|
||||
}
|
||||
|
||||
async auth(username: string, password: string) {
|
||||
async auth(username: string, password: string): Promise<SessionId | undefined> {
|
||||
const url = new URL(this.base);
|
||||
url.pathname = `api/v1/auth`
|
||||
return fetch(url, { method: 'PUT', headers: [['Content-Type', 'application/json']], body: JSON.stringify({ 'username': username, 'password': password }) });
|
||||
url.pathname = `/api/v1/auth`
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: [['Content-Type', 'application/json']],
|
||||
body: JSON.stringify({ 'username': username, 'password': password })
|
||||
});
|
||||
const session_id: SessionId = await response.json();
|
||||
return session_id;
|
||||
}
|
||||
|
||||
async status() {
|
||||
async profile(sessionId: SessionId, userId: UserId | undefined): Promise<UserProfile | undefined> {
|
||||
const url = new URL(this.base);
|
||||
url.pathname = `/api/v1/status`;
|
||||
if (userId) {
|
||||
url.pathname = `/api/v1/user${userId}`
|
||||
} else {
|
||||
url.pathname = `/api/v1/user`
|
||||
}
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: [['Authorization', `Bearer ${sessionId}`]],
|
||||
});
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
async health() {
|
||||
const url = new URL(this.base);
|
||||
url.pathname = `/api/v1/health`;
|
||||
return fetch(url).then((response) => response.json());
|
||||
}
|
||||
|
||||
|
0
visions/ui/src/components/Profile/Profile.css
Normal file
0
visions/ui/src/components/Profile/Profile.css
Normal file
12
visions/ui/src/components/Profile/Profile.tsx
Normal file
12
visions/ui/src/components/Profile/Profile.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { UserProfile } from 'visions-types';
|
||||
|
||||
export const ProfileElement = ({ name, games, is_admin }: UserProfile) => {
|
||||
const adminNote = is_admin ? <div> <i>Note: this user is an admin</i> </div> : <></>;
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
<h1>{name}</h1>
|
||||
<div>Games: {games.map((game) => <>{game.game_name} ({game.game_type})</>).join(', ')}</div>
|
||||
{adminNote}
|
||||
</div>)
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import React, { useContext } from 'react';
|
||||
import './Tabletop.css';
|
||||
import { RGB } from 'visions-types';
|
||||
import { Rgb } from 'visions-types';
|
||||
|
||||
interface TabletopElementProps {
|
||||
backgroundColor: RGB;
|
||||
backgroundColor: Rgb;
|
||||
backgroundUrl: URL | undefined;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ProfileElement } from './Profile/Profile'
|
||||
import { SimpleGuage } from './Guages/SimpleGuage'
|
||||
import { ThumbnailElement } from './Thumbnail/Thumbnail'
|
||||
import { TabletopElement } from './Tabletop/Tabletop'
|
||||
import { SimpleGuage } from './Guages/SimpleGuage'
|
||||
|
||||
export default { ThumbnailElement, TabletopElement, SimpleGuage }
|
||||
export { ProfileElement, ThumbnailElement, TabletopElement, SimpleGuage }
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { assertNever } from '.';
|
||||
import { assertNever } from '../../utils';
|
||||
import './Charsheet.css';
|
||||
import { DriveGuage } from './DriveGuage/DriveGuage';
|
||||
import { Charsheet, Nerve, Cunning, Intuition } from './types';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { assertNever } from '.';
|
||||
import { SimpleGuage } from '../../components/Guages/SimpleGuage';
|
||||
import { Charsheet, Nerve, Cunning, Intuition } from './types';
|
||||
import './CharsheetPanel.css';
|
||||
import classNames from 'classnames';
|
||||
import { assertNever } from '../../utils';
|
||||
|
||||
interface CharsheetPanelProps {
|
||||
sheet: Charsheet;
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { CharsheetElement } from './Charsheet';
|
||||
import { CharsheetPanelElement } from './CharsheetPanel';
|
||||
|
||||
export function assertNever(value: never) {
|
||||
throw new Error("Unexpected value: " + value);
|
||||
}
|
||||
|
||||
export default { CharsheetElement, CharsheetPanelElement };
|
||||
|
||||
|
@ -1,27 +1,63 @@
|
||||
import React, { createContext, PropsWithChildren, useCallback, useEffect, useReducer, useRef } from "react";
|
||||
import { Status, Tabletop } from "visions-types";
|
||||
import { SessionId, Status, Tabletop } from "visions-types";
|
||||
import { Client } from "../../client";
|
||||
import { assertNever } from "../../plugins/Candela";
|
||||
import { assertNever } from "../../utils";
|
||||
|
||||
type AuthState = { type: "NoAdmin" } | { type: "Unauthed" } | { type: "Authed", userid: string };
|
||||
type AuthState = { type: "NoAdmin" } | { type: "Unauthed" } | { type: "Authed", sessionId: string };
|
||||
|
||||
export enum LoadingState {
|
||||
Loading,
|
||||
Ready,
|
||||
}
|
||||
|
||||
type AppState = {
|
||||
auth: AuthState;
|
||||
tabletop: Tabletop;
|
||||
state: LoadingState,
|
||||
auth: AuthState,
|
||||
tabletop: Tabletop,
|
||||
}
|
||||
|
||||
type Action = { type: "SetAuthState", content: AuthState };
|
||||
|
||||
const initialState = (): AppState => (
|
||||
{
|
||||
const initialState = (): AppState => {
|
||||
let state: AppState = {
|
||||
state: LoadingState.Ready,
|
||||
auth: { type: "NoAdmin" },
|
||||
tabletop: { backgroundColor: { red: 0, green: 0, blue: 0 }, backgroundImage: undefined }
|
||||
tabletop: { backgroundColor: { red: 0, green: 0, blue: 0 }, backgroundImage: undefined },
|
||||
}
|
||||
|
||||
const sessionId = window.localStorage.getItem("sessionId")
|
||||
if (sessionId) {
|
||||
return { ...state, auth: { type: "Authed", sessionId } }
|
||||
} else {
|
||||
return state
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const stateReducer = (state: AppState, action: Action): AppState => {
|
||||
switch (action.type) {
|
||||
case "SetAuthState": {
|
||||
return { ...state, auth: action.content }
|
||||
}
|
||||
/*
|
||||
default: {
|
||||
assertNever(action)
|
||||
return state
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
export const getSessionId = (state: AppState): SessionId | undefined => {
|
||||
switch (state.auth.type) {
|
||||
case "NoAdmin": return undefined
|
||||
case "Unauthed": return undefined
|
||||
case "Authed": return state.auth.sessionId
|
||||
default: {
|
||||
assertNever(state.auth)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class StateManager {
|
||||
client: Client | undefined;
|
||||
@ -35,11 +71,9 @@ class StateManager {
|
||||
async status() {
|
||||
if (!this.client || !this.dispatch) return;
|
||||
|
||||
const { admin_enabled } = await this.client.status();
|
||||
const { admin_enabled } = await this.client.health();
|
||||
if (!admin_enabled) {
|
||||
this.dispatch({ type: "SetAuthState", content: { type: "NoAdmin" } });
|
||||
} else {
|
||||
this.dispatch({ type: "SetAuthState", content: { type: "Unauthed" } });
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,10 +87,11 @@ class StateManager {
|
||||
async auth(username: string, password: string) {
|
||||
if (!this.client || !this.dispatch) return;
|
||||
|
||||
let resp = await this.client.auth(username, password);
|
||||
let userid = await resp.json();
|
||||
console.log("userid retrieved", userid);
|
||||
this.dispatch({ type: "SetAuthState", content: { type: "Authed", userid } });
|
||||
let sessionId = await this.client.auth(username, password);
|
||||
if (sessionId) {
|
||||
window.localStorage.setItem("sessionId", sessionId);
|
||||
this.dispatch({ type: "SetAuthState", content: { type: "Authed", sessionId } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
4
visions/ui/src/utils.ts
Normal file
4
visions/ui/src/utils.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export function assertNever(value: never) {
|
||||
throw new Error("Unexpected value: " + value);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { PropsWithChildren, useContext, useState } from 'react';
|
||||
import { StateContext } from '../../providers/StateProvider/StateProvider';
|
||||
import { assertNever } from '../../plugins/Candela';
|
||||
import { LoadingState, StateContext } from '../../providers/StateProvider/StateProvider';
|
||||
import { assertNever } from '../../utils';
|
||||
import './Authentication.css';
|
||||
|
||||
interface AuthenticationProps {
|
||||
@ -17,6 +17,11 @@ export const Authentication = ({ onAdminPassword, onAuth, children }: PropsWithC
|
||||
let [pwField, setPwField] = useState<string>("");
|
||||
let [state, _] = useContext(StateContext);
|
||||
|
||||
switch (state.state) {
|
||||
case LoadingState.Loading: {
|
||||
return <div>Loading</div>
|
||||
}
|
||||
case LoadingState.Ready: {
|
||||
switch (state.auth.type) {
|
||||
case "NoAdmin": {
|
||||
return <div className="auth">
|
||||
@ -49,3 +54,6 @@ export const Authentication = ({ onAdminPassword, onAuth, children }: PropsWithC
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
.gm-view {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Client } from '../../client';
|
||||
import { StateContext } from '../../providers/StateProvider/StateProvider';
|
||||
import { TabletopElement } from '../../components/Tabletop/Tabletop';
|
||||
import { ThumbnailElement } from '../../components/Thumbnail/Thumbnail';
|
||||
import { WebsocketContext } from '../../components/WebsocketProvider';
|
||||
import './GmView.css';
|
||||
|
||||
interface GmViewProps {
|
||||
client: Client
|
||||
}
|
||||
|
||||
export const GmView = ({ client }: GmViewProps) => {
|
||||
const [state, dispatch] = useContext(StateContext);
|
||||
|
||||
const [images, setImages] = useState<string[]>([]);
|
||||
useEffect(() => {
|
||||
client.availableImages().then((images) => setImages(images));
|
||||
}, [client]);
|
||||
|
||||
const backgroundUrl = state.tabletop.backgroundImage ? client.imageUrl(state.tabletop.backgroundImage) : undefined;
|
||||
return (<div className="gm-view">
|
||||
<div>
|
||||
{images.map((imageName) => <ThumbnailElement id={imageName} url={client.imageUrl(imageName)} onclick={() => { client.setBackgroundImage(imageName); }} />)}
|
||||
</div>
|
||||
<TabletopElement backgroundColor={state.tabletop.backgroundColor} backgroundUrl={backgroundUrl} />
|
||||
</div>)
|
||||
}
|
||||
|
0
visions/ui/src/views/Main/Main.css
Normal file
0
visions/ui/src/views/Main/Main.css
Normal file
29
visions/ui/src/views/Main/Main.tsx
Normal file
29
visions/ui/src/views/Main/Main.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { UserProfile } from 'visions-types';
|
||||
import { Client } from '../../client';
|
||||
import { ProfileElement } from '../../components';
|
||||
import { getSessionId, StateContext, StateProvider } from '../../providers/StateProvider/StateProvider';
|
||||
|
||||
interface MainProps {
|
||||
client: Client
|
||||
}
|
||||
|
||||
export const MainView = ({ client }: MainProps) => {
|
||||
const [state, _manager] = useContext(StateContext)
|
||||
const [profile, setProfile] = useState<UserProfile | undefined>(undefined)
|
||||
|
||||
const sessionId = getSessionId(state)
|
||||
useEffect(() => {
|
||||
if (sessionId) {
|
||||
client.profile(sessionId, undefined).then((profile) => setProfile(profile))
|
||||
}
|
||||
}, [sessionId, client])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Session ID: {sessionId}</div>
|
||||
{profile && <ProfileElement {...profile} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
.player-view {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.player-view__left-panel {
|
||||
min-width: 100px;
|
||||
max-width: 20%;
|
||||
}
|
||||
|
||||
.player-view__right-panel {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import './PlayerView.css';
|
||||
import { WebsocketContext } from '../../components/WebsocketProvider';
|
||||
import { Client } from '../../client';
|
||||
import { TabletopElement } from '../../components/Tabletop/Tabletop';
|
||||
import Candela from '../../plugins/Candela';
|
||||
import { StateContext } from '../../providers/StateProvider/StateProvider';
|
||||
|
||||
const TEST_CHARSHEET_UUID = "12df9c09-1f2f-4147-8eda-a97bd2a7a803";
|
||||
|
||||
interface PlayerViewProps {
|
||||
client: Client;
|
||||
}
|
||||
|
||||
export const PlayerView = ({ client }: PlayerViewProps) => {
|
||||
const [state, dispatch] = useContext(StateContext);
|
||||
|
||||
const [charsheet, setCharsheet] = useState(undefined);
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
client.charsheet(TEST_CHARSHEET_UUID).then((c) => {
|
||||
setCharsheet(c)
|
||||
});
|
||||
},
|
||||
[client, setCharsheet]
|
||||
);
|
||||
|
||||
const backgroundColor = state.tabletop.backgroundColor;
|
||||
const tabletopColorStyle = `rgb(${backgroundColor.red}, ${backgroundColor.green}, ${backgroundColor.blue})`;
|
||||
const backgroundUrl = state.tabletop.backgroundImage ? client.imageUrl(state.tabletop.backgroundImage) : undefined;
|
||||
|
||||
return (<div className="player-view" style={{ backgroundColor: tabletopColorStyle }}>
|
||||
<div className="player-view__middle-panel"> <TabletopElement backgroundColor={backgroundColor} backgroundUrl={backgroundUrl} /> </div>
|
||||
<div className="player-view__right-panel">
|
||||
{charsheet ? <Candela.CharsheetPanelElement sheet={charsheet} /> : <div> </div>}</div>
|
||||
</div>)
|
||||
}
|
||||
|
3
visions/ui/src/views/index.ts
Normal file
3
visions/ui/src/views/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { MainView } from './Main/Main'
|
||||
|
||||
export { MainView }
|
Loading…
Reference in New Issue
Block a user