diff --git a/apps/commons/custom_utils/Cargo.toml b/apps/commons/custom_utils/Cargo.toml deleted file mode 100644 index 79b94bcb8..000000000 --- a/apps/commons/custom_utils/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "custom_utils" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -relm4 = "0.7.0-beta.1" -relm4-components = "0.7.0-beta.1" -relm4-macros = "0.7.0-beta.1" -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -custom_widgets = { path = "../custom_widgets"} \ No newline at end of file diff --git a/apps/commons/custom_utils/src/lib.rs b/apps/commons/custom_utils/src/lib.rs deleted file mode 100644 index 865f09b72..000000000 --- a/apps/commons/custom_utils/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -use gtk::{gdk, gio}; -use relm4::gtk::{self, prelude::FileExt}; -use custom_widgets::gif_paintable::GifPaintable; - -pub fn get_image_from_path(path: Option, css_classes: &[&str]) -> gtk::Image { - let image = gtk::Image::builder().css_classes(css_classes).build(); - - match path { - Some(p) => { - let image_file = gio::File::for_path(p); - match gdk::Texture::from_file(&image_file){ - Ok(image_asset_paintable) => { - image.set_paintable(Option::from(&image_asset_paintable)); - }, - Err(_) => (), - } - } - None => (), - } - image -} - - -pub fn get_gif_from_path(gif_path: Option) -> GifPaintable { - let paintable = GifPaintable::new(); - - match gif_path { - Some(path) => { - let image_file = gio::File::for_path(path); - match image_file.load_contents(gio::Cancellable::NONE) { - Ok((bytes, _)) => { - let _ = paintable.load_from_bytes(&bytes); - } - Err(_) => (), - }; - } - None => (), - } - paintable -} diff --git a/apps/commons/custom_widgets/Cargo.toml b/apps/commons/custom_widgets/Cargo.toml deleted file mode 100644 index 6b89d2f24..000000000 --- a/apps/commons/custom_widgets/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "custom_widgets" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -relm4 = "0.7.0-beta.1" -relm4-components = "0.7.0-beta.1" -relm4-macros = "0.7.0-beta.1" -anyhow = "1.0.71" -serde = { version = "1.0.163", features = ["derive",] } -serde_yaml = "0.9.21" -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -image = "0.24.7" \ No newline at end of file diff --git a/apps/commons/custom_widgets/src/assets/css/style.css b/apps/commons/custom_widgets/src/assets/css/style.css deleted file mode 100644 index 00349565a..000000000 --- a/apps/commons/custom_widgets/src/assets/css/style.css +++ /dev/null @@ -1,30 +0,0 @@ -entry { - background: transparent; - color: #E4E7EE; - outline: none; - border: none; - padding: 0px; - border-radius: 4px; -} - -entry :focus { - background: transparent; - outline: none; - border: none; -} - -entry :focus-visible { - background: transparent; - outline: none; - border: none; -} - -entry :focus-within { - background: transparent; - outline: none; - border: none; -} - -.icon-input-icon-default { - padding: 10px; -} \ No newline at end of file diff --git a/apps/commons/custom_widgets/src/gif_paintable/frame.rs b/apps/commons/custom_widgets/src/gif_paintable/frame.rs deleted file mode 100644 index 253c8ac65..000000000 --- a/apps/commons/custom_widgets/src/gif_paintable/frame.rs +++ /dev/null @@ -1,38 +0,0 @@ -use gtk::prelude::*; -use gtk::{gdk, glib}; -use relm4::gtk; -use std::time::Duration; - -pub struct Frame { - pub texture: gdk::Texture, - pub frame_duration: Duration, -} - -impl From for Frame { - fn from(f: image::Frame) -> Self { - let mut frame_duration = Duration::from(f.delay()); - - // convention is to use 100 milliseconds duration if it is defined as 0. - if frame_duration.is_zero() { - frame_duration = Duration::from_millis(100); - } - - let samples = f.into_buffer().into_flat_samples(); - - let bytes = glib::Bytes::from(samples.as_slice()); - let layout = samples.layout; - - let texture = gdk::MemoryTexture::new( - layout.width as i32, - layout.height as i32, - gdk::MemoryFormat::R8g8b8a8, - &bytes, - layout.height_stride, - ); - - Frame { - texture: texture.upcast(), - frame_duration, - } - } -} diff --git a/apps/commons/custom_widgets/src/gif_paintable/imp.rs b/apps/commons/custom_widgets/src/gif_paintable/imp.rs deleted file mode 100644 index 33044097c..000000000 --- a/apps/commons/custom_widgets/src/gif_paintable/imp.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::cell::{Cell, RefCell}; - -use gtk::prelude::*; -use gtk::subclass::prelude::*; -use gtk::{gdk, glib, graphene}; -use relm4::gtk; - -use super::Frame; - -#[derive(Default)] -pub struct GifPaintable { - pub frames: RefCell>>, - pub next_frame: RefCell>, - pub timeout_source_id: RefCell>, - pub current_idx: Cell, -} - -#[glib::object_subclass] -impl ObjectSubclass for GifPaintable { - const NAME: &'static str = "GifPaintable"; - type Type = super::GifPaintable; - type Interfaces = (gdk::Paintable,); -} - -impl ObjectImpl for GifPaintable {} - -impl PaintableImpl for GifPaintable { - fn intrinsic_height(&self) -> i32 { - self.next_frame - .borrow() - .as_ref() - .map(|texture| texture.height()) - .unwrap_or(-1) - } - - fn intrinsic_width(&self) -> i32 { - self.next_frame - .borrow() - .as_ref() - .map(|texture| texture.width()) - .unwrap_or(-1) - } - - fn snapshot(&self, snapshot: &gdk::Snapshot, width: f64, height: f64) { - if let Some(texture) = &*self.next_frame.borrow() { - texture.snapshot(snapshot, width, height); - } else { - snapshot.append_color( - &gdk::RGBA::BLACK, - &graphene::Rect::new(0f32, 0f32, width as f32, height as f32), - ); - } - } -} diff --git a/apps/commons/custom_widgets/src/gif_paintable/mod.rs b/apps/commons/custom_widgets/src/gif_paintable/mod.rs deleted file mode 100644 index 955b57f10..000000000 --- a/apps/commons/custom_widgets/src/gif_paintable/mod.rs +++ /dev/null @@ -1,106 +0,0 @@ -mod imp; -mod frame; - -use relm4::gtk; -use std::io::Cursor; - -use frame::Frame; -use gtk::prelude::*; -use gtk::subclass::prelude::*; -use gtk::{gdk, glib}; -use image::{codecs::gif::GifDecoder, AnimationDecoder}; - -glib::wrapper! { - pub struct GifPaintable(ObjectSubclass) @implements gdk::Paintable; -} - -impl GifPaintable { - pub fn new() -> Self { - glib::Object::new() - } - - /// Loads the bytes of a GIF into the paintable. - /// - /// The loading consists of decoding the gif with a GIFDecoder, then storing - /// the frames so that the paintable can render them. - pub fn load_from_bytes(&self, bytes: &[u8]) -> Result<(), Box> { - let imp = self.imp(); - imp.current_idx.set(0); - - if let Some(source_id) = imp.timeout_source_id.take() { - source_id.remove(); - } - - let read = Cursor::new(bytes); - - // Images from unknown origins make a program vulnerable to - // decompression bombs. That is, malicious images crafted specifically - // to require an enormous amount of memory to process while having a - // disproportionately small file size. - // - // By default, `GifDecoder::new()` limits the allocation of a single - // frame to 50MB, but it can be restricted further with - // `GifDecoder::with_limits()`. - // - // An safety measure to guard against that would be to process each - // frame as needed instead of loading them all with `collect_frames()`. - let decoder = GifDecoder::new(read)?; - - let frames = decoder - .into_frames() - .collect_frames()? - .into_iter() - .map(Frame::from) - .collect::>(); - - imp.frames.replace(Some(frames)); - - // make sure the first frame is queued to play - self.setup_next_frame(); - - Ok(()) - } - - fn setup_next_frame(&self) { - let imp = self.imp(); - let idx = imp.current_idx.get(); - let frames_ref = imp.frames.borrow(); - - // if we have stored no frames then we early return early - // and instead render a default frame in `imp::GifPaintable::snapshot` - let frames = match &*frames_ref { - Some(frames) => frames, - None => return, - }; - - let next_frame = frames.get(idx).unwrap(); - imp.next_frame.replace(Some(next_frame.texture.clone())); - - // invalidate the contents so that the new frame will be rendered - self.invalidate_contents(); - - // setup a callback to this function once the frame has finished so that - // we can play the next frame - let update_next_frame_callback = glib::clone!(@weak self as paintable => move || { - paintable.imp().timeout_source_id.take(); - paintable.setup_next_frame(); - }); - - let source_id = - glib::timeout_add_local_once(next_frame.frame_duration, update_next_frame_callback); - imp.timeout_source_id.replace(Some(source_id)); - - // setup the index for the next call to setup_next_frame - let mut new_idx = idx + 1; - if new_idx >= frames.len() { - new_idx = 0; - } - imp.current_idx.set(new_idx); - } -} - -impl Default for GifPaintable { - fn default() -> Self { - Self::new() - } -} \ No newline at end of file diff --git a/apps/commons/custom_widgets/src/icon_button.rs b/apps/commons/custom_widgets/src/icon_button.rs deleted file mode 100644 index 9e1abc77d..000000000 --- a/apps/commons/custom_widgets/src/icon_button.rs +++ /dev/null @@ -1,194 +0,0 @@ -use gtk::{gdk, gio, glib::clone, prelude::*, subclass::*}; -use relm4::{ - gtk::{self, GestureClick}, - ComponentParts, RelmWidgetExt, SimpleComponent, -}; -use tracing::info; - -#[derive(Debug, Clone)] -pub struct IconButtonCss { - root_container: Option>, - container: Option>, - container_pressing: Option, - icon: Option>, -} - -impl Default for IconButtonCss { - fn default() -> Self { - Self { - root_container: Option::from(vec!["icon-button-root-default".to_string()]), - container: Option::from(vec!["icon-button-container-default".to_string()]), - container_pressing: Option::from("icon-button-container-pressing-default".to_string()), - icon: Option::from(vec!["icon-button-icon-default".to_string()]), - } - } -} - -#[derive(Debug)] -pub struct InitSettings { - pub icon: Option, - pub toggle_icon: Option, - pub css: IconButtonCss, -} - -#[derive(Debug)] -pub enum InputMessage { - Pressed, - Released, -} - -#[derive(Debug)] -pub enum OutputMessage { - Clicked, -} - -pub struct IconButton { - settings: InitSettings, - is_in_pressing_state: bool, -} - -pub struct ComponentWidgets { - container_box: gtk::Box, - icon_image: gtk::Image, -} - -impl SimpleComponent for IconButton { - type Input = InputMessage; - - type Output = OutputMessage; - - type Init = InitSettings; - - type Root = gtk::Box; - - type Widgets = ComponentWidgets; - - fn init_root() -> Self::Root { - let root_box = gtk::Box::builder() - .valign(gtk::Align::Center) - .hexpand(false) - .vexpand(false) - .build(); - root_box - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: relm4::ComponentSender, - ) -> relm4::ComponentParts { - info!("icon button init called"); - - match init.css.root_container.to_owned() { - Some(css) => root.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let container_box = gtk::Box::builder() - .valign(gtk::Align::Center) - .hexpand(true) - .vexpand(true) - .build(); - - match init.css.container.to_owned() { - Some(css) => container_box.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let icon = init.icon.clone(); - let icon_image = gtk::Image::builder().hexpand(true).vexpand(true).build(); - match icon.to_owned() { - Some(icon) => { - let icon_file = gio::File::for_path(icon); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - icon_image.set_paintable(Option::from(&asset_paintable)); - match init.css.icon.to_owned() { - Some(css) => icon_image.set_css_classes(&[css.join(",").as_str()]), - None => (), - }; - container_box.append(&icon_image); - - let left_click_gesture = GestureClick::builder().button(0).build(); - left_click_gesture.connect_pressed(clone!(@strong sender => move |this, _, _,_| { - info!("gesture button pressed is {}", this.current_button()); - sender.input_sender().send(InputMessage::Pressed); - - })); - - left_click_gesture.connect_released(clone!(@strong sender => move |this, _, _,_| { - info!("gesture button released is {}", this.current_button()); - sender.input_sender().send(InputMessage::Released); - - })); - root.add_controller(left_click_gesture); - } - None => (), - } - - root.append(&container_box); - - let model = IconButton { - settings: init, - is_in_pressing_state: false, - }; - - let widgets = ComponentWidgets { - container_box, - icon_image, - }; - - ComponentParts { model, widgets } - } - - fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender) { - info!("icon button update message {:?}", message); - match message { - InputMessage::Pressed => { - self.is_in_pressing_state = true; - } - InputMessage::Released => { - self.is_in_pressing_state = false; - let _ = sender.output_sender().send(OutputMessage::Clicked); - } - } - } - - fn update_view(&self, widgets: &mut Self::Widgets, sender: relm4::ComponentSender) { - match self.settings.css.container_pressing.to_owned() { - Some(css) => { - widgets - .container_box - .set_class_active(&css.as_str(), self.is_in_pressing_state); - } - None => (), - } - match self.settings.toggle_icon.to_owned() { - Some(icon) => match self.is_in_pressing_state { - true => { - widgets.icon_image.set_file(Option::from(icon.as_str())); - } - false => { - widgets - .icon_image - .set_file(Option::from(self.settings.icon.clone().unwrap().as_str())); - } - }, - None => (), - } - } - - fn shutdown(&mut self, widgets: &mut Self::Widgets, output: relm4::Sender) { - info!("icon button sutdown called"); - } -} - -// fn load_image(icon: String, hexpand: bool, vexpand: bool) -> gtk::Image { -// let icon_file = gio::File::for_path(icon); -// let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); -// let image = gtk::Image::builder() -// .hexpand(hexpand) -// .vexpand(vexpand) -// .build(); -// image.set_paintable(Option::from(&asset_paintable)); -// image -// } diff --git a/apps/commons/custom_widgets/src/icon_input.rs b/apps/commons/custom_widgets/src/icon_input.rs deleted file mode 100644 index 91eb11ab6..000000000 --- a/apps/commons/custom_widgets/src/icon_input.rs +++ /dev/null @@ -1,262 +0,0 @@ -use gtk::gdk::Display; -use gtk::{ - gdk, gio, - glib::{clone, object::ObjectExt}, - prelude::*, - subclass::*, -}; -use relm4::gtk::STYLE_PROVIDER_PRIORITY_APPLICATION; -use relm4::{ - gtk::{self, CssProvider, GestureClick}, - ComponentParts, RelmWidgetExt, SimpleComponent, -}; -use tracing::{error, info}; - -#[derive(Debug, Clone)] -pub struct IconInputCss { - root_container: Option>, - root_container_focused: Option>, - container: Option>, - icon: Option>, -} - -impl Default for IconInputCss { - fn default() -> Self { - Self { - root_container: Option::from(vec!["icon-input-root-default".to_string()]), - root_container_focused: Option::from(vec![ - "icon-input-root-focused-default".to_string() - ]), - container: Option::from(vec!["icon-input-container-default".to_string()]), - icon: Option::from(vec!["icon-input-icon-default".to_string()]), - } - } -} - -#[derive(Default, Debug, Clone)] -pub enum IconPosition { - #[default] - Left, - Right, -} - -#[derive(Debug, Clone)] -pub struct IconSettings { - pub path: String, - pub position: IconPosition, -} - -#[derive(Debug, Clone)] -pub struct InitSettings { - pub placeholder: Option, - pub icon: Option, - pub clear_icon: Option, - pub css: IconInputCss, -} - -#[derive(Debug)] -pub enum InputMessage { - InputChange(String), - InputFocusEnter, - InputFocusLeave, - Clear, -} - -#[derive(Debug)] -pub enum OutputMessage { - InputChange(String), -} - -pub struct IconInput { - settings: InitSettings, - view_password: bool, - is_focused: bool, - input: gtk::Entry, -} - -pub struct ComponentWidgets { - container_box: gtk::Box, - icon_image: gtk::Image, - root: gtk::Box, - clear_icon_image: gtk::Image -} - -impl SimpleComponent for IconInput { - type Input = InputMessage; - - type Output = OutputMessage; - - type Init = InitSettings; - - type Root = gtk::Box; - - type Widgets = ComponentWidgets; - - fn init_root() -> Self::Root { - // The CSS "magic" happens here. - let provider = CssProvider::new(); - provider.load_from_data(include_str!("assets/css/style.css")); - // We give the CssProvided to the default screen so the CSS rules we added - // can be applied to our window. - gtk::style_context_add_provider_for_display( - &Display::default().expect("Could not connect to a display."), - &provider, - STYLE_PROVIDER_PRIORITY_APPLICATION, - ); - let root_box = gtk::Box::builder() - .hexpand(true) - .vexpand(false) - .orientation(gtk::Orientation::Horizontal) - .build(); - root_box - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: relm4::ComponentSender, - ) -> relm4::ComponentParts { - info!("icon button init called"); - - match init.css.root_container.to_owned() { - Some(css) => root.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let container_box = gtk::Box::builder() - .valign(gtk::Align::Center) - .hexpand(true) - .vexpand(true) - .build(); - - match init.css.container.to_owned() { - Some(css) => container_box.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let input = gtk::Entry::builder().hexpand(true).build(); - - let event_controller = gtk::EventControllerFocus::builder().build(); - - event_controller.connect_enter(clone!(@strong sender => move |_| { - sender.input(InputMessage::InputFocusEnter); - })); - - event_controller.connect_leave(clone!(@strong sender => move |_| { - sender.input(InputMessage::InputFocusLeave); - })); - - input.add_controller(event_controller); - - input.connect_changed(clone!(@strong sender => move |entry| { - sender.input(InputMessage::InputChange(entry.text().into())); - })); - - let icon_image = gtk::Image::builder().hexpand(false).vexpand(false).build(); - - match init.placeholder.clone() { - Some(placeholder) => { - input.set_placeholder_text(Option::from(placeholder.as_str())); - } - None => (), - } - - root.append(&input); - - match init.icon.clone() { - Some(icon) => { - let icon_file = gio::File::for_path(icon.path); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - icon_image.set_paintable(Option::from(&asset_paintable)); - match init.css.icon.to_owned() { - Some(css) => icon_image.set_css_classes(&[css.join(",").as_str()]), - None => (), - }; - match icon.position { - IconPosition::Left => root.prepend(&icon_image), - IconPosition::Right => root.append(&icon_image), - }; - } - None => (), - } - - let clear_icon_image = gtk::Image::builder() - .visible(false) - .hexpand(false) - .vexpand(false) - .build(); - match init.clear_icon.clone() { - Some(icon) => { - let icon_file = gio::File::for_path(icon.path); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - clear_icon_image.set_paintable(Option::from(&asset_paintable)); - match init.css.icon.to_owned() { - Some(css) => clear_icon_image.set_css_classes(&[css.join(",").as_str()]), - None => (), - }; - match icon.position { - IconPosition::Left => root.prepend(&clear_icon_image), - IconPosition::Right => root.append(&clear_icon_image), - }; - let left_click_gesture = GestureClick::builder().button(0).build(); - - left_click_gesture.connect_released(clone!(@strong sender => move |this, _, _,_| { - sender.input_sender().send(InputMessage::Clear); - - })); - clear_icon_image.add_controller(left_click_gesture); - } - None => (), - } - - let model = IconInput { - settings: init, - view_password: false, - is_focused: false, - input, - }; - - let widgets = ComponentWidgets { - container_box, - icon_image, - root: root.clone(), - clear_icon_image - }; - - ComponentParts { model, widgets } - } - - fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender) { - info!("icon button update message {:?}", message); - match message { - InputMessage::InputChange(text) => { - let _ = sender - .output_sender() - .send(OutputMessage::InputChange(text)); - } - InputMessage::InputFocusEnter => { - self.is_focused = true; - } - InputMessage::InputFocusLeave => { - self.is_focused = false; - } - InputMessage::Clear => { - self.input.set_text(""); - } - } - } - - fn update_view(&self, widgets: &mut Self::Widgets, sender: relm4::ComponentSender) { - match self.settings.css.root_container_focused.to_owned() { - Some(css) => widgets - .root - .set_class_active(&css.join(",").as_str(), self.is_focused), - None => (), - } - widgets.clear_icon_image.set_visible(self.is_focused); - } - - fn shutdown(&mut self, widgets: &mut Self::Widgets, output: relm4::Sender) { - info!("icon button sutdown called"); - } -} diff --git a/apps/commons/custom_widgets/src/icon_input_password.rs b/apps/commons/custom_widgets/src/icon_input_password.rs deleted file mode 100644 index 1218f7541..000000000 --- a/apps/commons/custom_widgets/src/icon_input_password.rs +++ /dev/null @@ -1,249 +0,0 @@ -use gtk::{ - gdk, gio, - glib::{clone, object::ObjectExt}, - prelude::*, - subclass::*, -}; -use relm4::{ - gtk::{self, GestureClick}, - ComponentParts, RelmWidgetExt, SimpleComponent, -}; -use tracing::{error, info}; - -#[derive(Debug, Clone)] -pub struct IconInputPasswordCss { - root_container: Option>, - root_container_focused: Option>, - container: Option>, - icon: Option>, -} - -impl Default for IconInputPasswordCss { - fn default() -> Self { - Self { - root_container: Option::from(vec!["icon-input-root-default".to_string()]), - root_container_focused: Option::from(vec![ - "icon-input-root-focused-default".to_string() - ]), - container: Option::from(vec!["icon-input-container-default".to_string()]), - icon: Option::from(vec!["icon-input-icon-default".to_string()]), - } - } -} - -#[derive(Debug)] -pub struct InitSettings { - pub placeholder: Option, - pub icon: Option, - pub toggle_icon: Option, - pub css: IconInputPasswordCss, -} - -#[derive(Debug)] -pub enum InputMessage { - ToggleViewPassword, - InputChange(String), - InputFocusEnter, - InputFocusLeave, -} - -#[derive(Debug)] -pub enum OutputMessage { - InputChange(String), -} - -pub struct IconInputPassword { - settings: InitSettings, - is_text_visible: bool, - is_focused: bool, -} - -pub struct ComponentWidgets { - container_box: gtk::Box, - icon_image: gtk::Image, - root: gtk::Box, - input: gtk::Entry, -} - -impl SimpleComponent for IconInputPassword { - type Input = InputMessage; - - type Output = OutputMessage; - - type Init = InitSettings; - - type Root = gtk::Box; - - type Widgets = ComponentWidgets; - - fn init_root() -> Self::Root { - let root_box = gtk::Box::builder() - .hexpand(true) - .vexpand(false) - .orientation(gtk::Orientation::Horizontal) - .build(); - root_box - } - - fn init( - init: Self::Init, - root: Self::Root, - sender: relm4::ComponentSender, - ) -> relm4::ComponentParts { - info!("icon button init called"); - - match init.css.root_container.to_owned() { - Some(css) => root.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let container_box = gtk::Box::builder() - .valign(gtk::Align::Center) - .hexpand(true) - .vexpand(true) - .build(); - - match init.css.container.to_owned() { - Some(css) => container_box.set_css_classes(&[css.join(",").as_str()]), - None => (), - } - - let input = gtk::Entry::builder() - .hexpand(true) - .visibility(false) - .build(); - - let event_controller = gtk::EventControllerFocus::builder().build(); - - event_controller.connect_enter(clone!(@strong sender => move |_| { - sender.input(InputMessage::InputFocusEnter); - })); - - event_controller.connect_leave(clone!(@strong sender => move |_| { - sender.input(InputMessage::InputFocusLeave); - })); - - input.add_controller(event_controller); - - input.connect_changed(clone!(@strong sender => move |entry| { - sender.input(InputMessage::InputChange(entry.text().into())); - })); - - let icon_image = gtk::Image::builder().hexpand(false).vexpand(false).build(); - - match init.placeholder.clone() { - Some(placeholder) => { - input.set_placeholder_text(Option::from(placeholder.as_str())); - } - None => (), - } - - root.append(&input); - - let icon = init.icon.clone(); - match icon.to_owned() { - Some(icon) => { - let icon_file = gio::File::for_path(icon); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - // let image = gtk::Image::builder() - // .paintable(&asset_paintable) - // .hexpand(true) - // .vexpand(true) - // .build(); - icon_image.set_paintable(Option::from(&asset_paintable)); - - match init.css.icon.to_owned() { - Some(css) => icon_image.set_css_classes(&[css.join(",").as_str()]), - None => (), - }; - root.append(&icon_image); - let left_click_gesture = GestureClick::builder().button(0).build(); - // left_click_gesture.connect_pressed(clone!(@strong sender => move |this, _, _,_| { - // info!("gesture button pressed is {}", this.current_button()); - // sender.input_sender().send(InputMessage::Pressed); - - // })); - - left_click_gesture.connect_released(clone!(@strong sender => move |this, _, _,_| { - info!("gesture button released is {}", this.current_button()); - sender.input_sender().send(InputMessage::ToggleViewPassword); - - })); - icon_image.add_controller(left_click_gesture); - } - None => (), - } - - let model = IconInputPassword { - settings: init, - is_text_visible: false, - is_focused: false, - }; - - let widgets = ComponentWidgets { - container_box, - icon_image, - root: root.clone(), - input, - }; - - ComponentParts { model, widgets } - } - - fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender) { - info!("icon button update message {:?}", message); - match message { - InputMessage::ToggleViewPassword => { - self.is_text_visible = !self.is_text_visible; - } - InputMessage::InputChange(text) => { - let _ = sender - .output_sender() - .send(OutputMessage::InputChange(text)); - } - InputMessage::InputFocusEnter => { - self.is_focused = true; - } - InputMessage::InputFocusLeave => { - self.is_focused = false; - } - } - } - - fn update_view(&self, widgets: &mut Self::Widgets, sender: relm4::ComponentSender) { - widgets.input.set_visibility(self.is_text_visible); - - match self.is_text_visible { - true => match self.settings.toggle_icon.to_owned() { - Some(icon) => { - let icon_file = gio::File::for_path(icon); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - widgets - .icon_image - .set_paintable(Option::from(&asset_paintable)); - } - None => (), - }, - false => match self.settings.icon.to_owned() { - Some(icon) => { - let icon_file = gio::File::for_path(icon); - let asset_paintable = gdk::Texture::from_file(&icon_file).unwrap(); - widgets - .icon_image - .set_paintable(Option::from(&asset_paintable)); - } - None => (), - }, - } - match self.settings.css.root_container_focused.to_owned() { - Some(css) => widgets - .root - .set_class_active(&css.join(",").as_str(), self.is_focused), - None => (), - } - } - - fn shutdown(&mut self, widgets: &mut Self::Widgets, output: relm4::Sender) { - info!("icon button sutdown called"); - } -} diff --git a/apps/commons/custom_widgets/src/lib.rs b/apps/commons/custom_widgets/src/lib.rs deleted file mode 100644 index 6d0d409b1..000000000 --- a/apps/commons/custom_widgets/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod icon_button; -pub mod icon_input; -pub mod icon_input_password; -pub mod gif_paintable; \ No newline at end of file diff --git a/apps/settings/package-lock.json b/apps/settings/package-lock.json index 249c3059b..e3c942d8e 100644 --- a/apps/settings/package-lock.json +++ b/apps/settings/package-lock.json @@ -8,9 +8,10 @@ "name": "settings-app", "version": "0.0.1", "dependencies": { - "@tauri-apps/api": "^1.6.0", + "@tauri-apps/api": "^1.5.6", "bits-ui": "^0.21.8", "clsx": "^2.1.1", + "svelte-french-toast": "^1.2.0", "tailwind-merge": "^2.3.0", "tailwind-variants": "^0.2.1" }, @@ -64,9 +65,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -75,9 +76,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -91,9 +92,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -107,9 +108,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -123,9 +124,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -139,9 +140,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -155,9 +156,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -171,9 +172,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -187,9 +188,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -203,9 +204,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -219,9 +220,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -235,9 +236,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -251,9 +252,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -267,9 +268,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -283,9 +284,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -299,9 +300,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -315,9 +316,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -331,9 +332,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -347,9 +348,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -363,9 +364,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -379,9 +380,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -395,9 +396,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -411,9 +412,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -427,9 +428,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -458,9 +459,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -521,31 +522,32 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.1.tgz", - "integrity": "sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.3.tgz", + "integrity": "sha512-1ZpCvYf788/ZXOhRQGFxnYQOVgeU+pi0i+d0Ow34La7qjIXETi6RNswGVKkA6KcDO8/+Ysu2E/CeUmmeEBDvTg==", "dependencies": { - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.3" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", - "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.6.tgz", + "integrity": "sha512-qiTYajAnh3P+38kECeffMSQgbvXty2VB6rS+42iWR4FPIlZjLK84E9qtLnMTLIpPz2znD/TaFqaiavMUrS+Hcw==", "dependencies": { "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.3" } }, "node_modules/@floating-ui/utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", - "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.3.tgz", + "integrity": "sha512-XGndio0l5/Gvd6CLIABvsav9HHezgDFFhDfHk1bvLfr9ni8dojqLSvBbotJEjmIwNHL7vK4QzBJTdBRoB+c1ww==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -595,12 +597,13 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@internationalized/date": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.3.tgz", - "integrity": "sha512-X9bi8NAEHAjD8yzmPYT2pdJsbe+tYSEBAfowtlxJVJdZR3aK8Vg7ZUT1Fm5M47KLzp/M1p1VwAaeSma3RT7biw==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.4.tgz", + "integrity": "sha512-qoVJVro+O0rBaw+8HPjUB1iH8Ihf8oziEnqMnvhJUSuVIrHOuZ6eNLHNvzXJKUvAtaDiqMnRlg8Z2mgh09BlUw==", "dependencies": { "@swc/helpers": "^0.5.0" } @@ -705,23 +708,6 @@ "svelte": ">=3 <5" } }, - "node_modules/@melt-ui/svelte/node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -770,9 +756,9 @@ "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", "cpu": [ "arm" ], @@ -783,9 +769,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", "cpu": [ "arm64" ], @@ -796,9 +782,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", "cpu": [ "arm64" ], @@ -809,9 +795,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", "cpu": [ "x64" ], @@ -822,9 +808,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", "cpu": [ "arm" ], @@ -835,9 +821,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", "cpu": [ "arm" ], @@ -848,9 +834,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", "cpu": [ "arm64" ], @@ -861,9 +847,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", "cpu": [ "arm64" ], @@ -874,9 +860,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", "cpu": [ "ppc64" ], @@ -887,9 +873,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", "cpu": [ "riscv64" ], @@ -900,9 +886,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", "cpu": [ "s390x" ], @@ -913,9 +899,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], @@ -926,9 +912,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", "cpu": [ "x64" ], @@ -939,9 +925,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", "cpu": [ "arm64" ], @@ -952,9 +938,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", "cpu": [ "ia32" ], @@ -965,9 +951,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", "cpu": [ "x64" ], @@ -978,30 +964,30 @@ ] }, "node_modules/@sveltejs/adapter-auto": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.0.tgz", - "integrity": "sha512-She5nKT47kwHE18v9NMe6pbJcvULr82u0V3yZ0ej3n1laWKGgkgdEABE9/ak5iDPs93LqsBkuIo51kkwCLBjJA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.2.tgz", + "integrity": "sha512-Mso5xPCA8zgcKrv+QioVlqMZkyUQ5MjDJiEPuG/Z7cV/5tmwV7LmcVWk5tZ+H0NCOV1x12AsoSpt/CwFwuVXMA==", "dev": true, "dependencies": { - "import-meta-resolve": "^4.0.0" + "import-meta-resolve": "^4.1.0" }, "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/adapter-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz", - "integrity": "sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", + "integrity": "sha512-/EBFydZDwfwFfFEuF1vzUseBoRziwKP7AoHAwv+Ot3M084sE/HTVBHf9mCmXfdM9ijprY5YEugZjleflncX5fQ==", "dev": true, "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/kit": { - "version": "2.5.8", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.8.tgz", - "integrity": "sha512-ZQXYaVHd1p0kDGwOi4l82i5kAiUQtrhMthDKtJi0zVzmNupKJ0ZlBVAoceuarCuIntPNctyQchW29h5DkFxd1Q==", + "version": "2.5.17", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.17.tgz", + "integrity": "sha512-wiADwq7VreR3ctOyxilAZOfPz3Jiy2IIp2C8gfafhTdQaVuGIHllfqQm8dXZKADymKr3uShxzgLZFT+a+CM4kA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1009,7 +995,7 @@ "cookie": "^0.6.0", "devalue": "^5.0.0", "esm-env": "^1.0.0", - "import-meta-resolve": "^4.0.0", + "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", @@ -1031,16 +1017,16 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.0.tgz", - "integrity": "sha512-sY6ncCvg+O3njnzbZexcVtUqOBE3iYmQPJ9y+yXSkOwG576QI/xJrBnQSRXFLGwJNBa0T78JEKg5cIR0WOAuUw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", + "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", "dev": true, "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", - "magic-string": "^0.30.9", + "magic-string": "^0.30.10", "svelte-hmr": "^0.16.0", "vitefu": "^0.2.5" }, @@ -1092,24 +1078,10 @@ "tailwindcss": ">=3.0.0 || insiders" } }, - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@tauri-apps/api": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.6.0.tgz", - "integrity": "sha512-rqI++FWClU5I2UBp4HXFvl+sBWkdigBkxnpJDQUWttNyG7IZP4FwQGhTNL5EOw0vI8i6eSAJ5frLqO7n7jbJdg==", - "license": "Apache-2.0 OR MIT", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz", + "integrity": "sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==", "engines": { "node": ">= 14.6.0", "npm": ">= 6.6.0", @@ -1353,16 +1325,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", - "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", + "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/type-utils": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/type-utils": "7.14.1", + "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1386,15 +1358,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", - "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4" }, "engines": { @@ -1414,13 +1386,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", - "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0" + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1431,13 +1403,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", - "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", + "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/utils": "7.14.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1458,9 +1430,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", - "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1471,13 +1443,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", - "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1499,15 +1471,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", - "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0" + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1521,12 +1493,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", - "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/types": "7.14.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1544,9 +1516,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "bin": { "acorn": "bin/acorn" }, @@ -1708,9 +1680,9 @@ } }, "node_modules/bits-ui": { - "version": "0.21.9", - "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.21.9.tgz", - "integrity": "sha512-tMoHi2QbsNKJsPDoXGi07OMx6F8LVMSNYMMcntFX4fPPvy+SJSeZYOKlBMmneiSg7smpWzg+h20q0q01OvyxZQ==", + "version": "0.21.10", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.21.10.tgz", + "integrity": "sha512-KuweEOKO0Rr8XX87dQh46G9mG0bZSmTqNxj5qBazz4OTQC+oPKui04/wP/ISsCOSGFomaRydTULqh4p+nsyc2g==", "dependencies": { "@internationalized/date": "^3.5.1", "@melt-ui/svelte": "0.76.2", @@ -1723,23 +1695,6 @@ "svelte": "^4.0.0 || ^5.0.0-next.118" } }, - "node_modules/bits-ui/node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1752,7 +1707,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1761,9 +1715,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "funding": [ { @@ -1780,10 +1734,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -1793,12 +1747,12 @@ } }, "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, "engines": { - "node": "*" + "node": ">=8.0.0" } }, "node_modules/callsites": { @@ -1819,9 +1773,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001618", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001618.tgz", - "integrity": "sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==", + "version": "1.0.30001637", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001637.tgz", + "integrity": "sha512-1x0qRI1mD1o9e+7mBI7XtzFAP4XszbHaVWsMiGbSPLYekKTJF7K+FNk6AsXH4sUpc+qrsI3pVgf1Jdl/uGkuSQ==", "dev": true, "funding": [ { @@ -1984,9 +1938,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2078,9 +2032,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.768", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.768.tgz", - "integrity": "sha512-z2U3QcvNuxdkk33YV7R1bVMNq7fL23vq3WfO5BHcqrm4TnDGReouBfYKLEFh5umoK1XACjEwp8mmnhXk2EJigw==", + "version": "1.4.812", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", + "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==", "dev": true }, "node_modules/emoji-regex": { @@ -2095,9 +2049,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -2107,29 +2061,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escalade": { @@ -2209,9 +2163,9 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "dependencies": { "semver": "^7.5.4" @@ -2236,23 +2190,22 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "2.39.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.39.0.tgz", - "integrity": "sha512-FXktBLXsrxbA+6ZvJK2z/sQOrUKyzSg3fNWK5h0reSCjr2fjAsc9ai/s/JvSl4Hgvz3nYVtTIMwarZH5RcB7BA==", + "version": "2.41.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.41.0.tgz", + "integrity": "sha512-gjU9Q/psxbWG1VNwYbEb0Q6U4W5PBGaDpYmO2zlQ+zlAMVS3Qt0luAK0ACi/tMSwRK6JENiySvMyJbO0YWmXSg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", - "debug": "^4.3.4", - "eslint-compat-utils": "^0.5.0", + "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", - "known-css-properties": "^0.31.0", + "known-css-properties": "^0.34.0", "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.16", - "semver": "^7.6.0", - "svelte-eslint-parser": ">=0.36.0 <1.0.0" + "postcss-selector-parser": "^6.1.0", + "semver": "^7.6.2", + "svelte-eslint-parser": "^0.39.2" }, "engines": { "node": "^14.17.0 || >=16.0.0" @@ -2262,7 +2215,7 @@ }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.155" }, "peerDependenciesMeta": { "svelte": { @@ -2270,6 +2223,19 @@ } } }, + "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -2461,7 +2427,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2514,9 +2479,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -2572,6 +2537,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -2748,6 +2714,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -2772,11 +2739,14 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2813,7 +2783,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -2841,9 +2810,9 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -2858,9 +2827,9 @@ } }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "bin": { "jiti": "bin/jiti.js" } @@ -2914,9 +2883,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz", - "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", "dev": true }, "node_modules/levn": { @@ -3013,11 +2982,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3034,9 +3003,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3057,9 +3026,9 @@ } }, "node_modules/minipass": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", - "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -3111,9 +3080,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", "funding": [ { "type": "github", @@ -3121,10 +3090,10 @@ } ], "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^18 || >=20" } }, "node_modules/natural-compare": { @@ -3228,6 +3197,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3445,6 +3419,18 @@ "postcss": "^8.2.14" } }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", @@ -3488,9 +3474,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3504,6 +3491,23 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3514,9 +3518,9 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -3529,9 +3533,9 @@ } }, "node_modules/prettier-plugin-svelte": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.3.tgz", - "integrity": "sha512-wJq8RunyFlWco6U0WJV5wNCM7zpBFakS76UBSbmzMGpncpK98NZABaE+s7n8/APDCEVNHXC5Mpq+MLebQtsRlg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.5.tgz", + "integrity": "sha512-vP/M/Goc8z4iVIvrwXwbrYVjJgA0Hf8PO1G4LBh/ocSt6vUP6sLvyu9F3ABEGr+dbKyxZjEKLkeFsWy/yYl0HQ==", "dev": true, "peerDependencies": { "prettier": "^3.0.0", @@ -3702,6 +3706,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -3714,9 +3719,9 @@ } }, "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -3729,22 +3734,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", "fsevents": "~2.3.2" } }, @@ -3798,6 +3803,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -3878,13 +3884,13 @@ } }, "node_modules/sorcery": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", - "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", + "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", - "buffer-crc32": "^0.2.5", + "buffer-crc32": "^1.0.0", "minimist": "^1.2.0", "sander": "^0.5.0" }, @@ -4029,15 +4035,16 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.3.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", - "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.11.0" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -4073,9 +4080,9 @@ } }, "node_modules/svelte": { - "version": "4.2.17", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.17.tgz", - "integrity": "sha512-N7m1YnoXtRf5wya5Gyx3TWuTddI4nAyayyIWFojiWV5IayDYNV5i2mRp/7qNGol4DtxEYxljmrbgp1HM6hUbmQ==", + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", + "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -4097,15 +4104,13 @@ } }, "node_modules/svelte-check": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.7.1.tgz", - "integrity": "sha512-U4uJoLCzmz2o2U33c7mPDJNhRYX/DNFV11XTUDlFxaKLsO7P+40gvJHMPpoRfa24jqZfST4/G9fGNcUGMO8NAQ==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", + "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", "picocolors": "^1.0.0", "sade": "^1.7.4", "svelte-preprocess": "^5.1.3", @@ -4119,9 +4124,9 @@ } }, "node_modules/svelte-eslint-parser": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.36.0.tgz", - "integrity": "sha512-/6YmUSr0FAVxW8dXNdIMydBnddPMHzaHirAZ7RrT21XYdgGGZMh0LQG6CZsvAFS4r2Y4ItUuCQc8TQ3urB30mQ==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.39.2.tgz", + "integrity": "sha512-87UwLuWTtDIuzWOhOi1zBL5wYVd07M5BK1qZ57YmXJB5/UmjUNJqGy3XSOhPqjckY1dATNV9y+mx+nI0WH6HPA==", "dev": true, "dependencies": { "eslint-scope": "^7.2.2", @@ -4145,6 +4150,18 @@ } } }, + "node_modules/svelte-french-toast": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/svelte-french-toast/-/svelte-french-toast-1.2.0.tgz", + "integrity": "sha512-5PW+6RFX3xQPbR44CngYAP1Sd9oCq9P2FOox4FZffzJuZI2mHOB7q5gJBVnOiLF5y3moVGZ7u2bYt7+yPAgcEQ==", + "license": "MIT", + "dependencies": { + "svelte-writable-derived": "^3.1.0" + }, + "peerDependencies": { + "svelte": "^3.57.0 || ^4.0.0" + } + }, "node_modules/svelte-hmr": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", @@ -4219,6 +4236,17 @@ } } }, + "node_modules/svelte-writable-derived": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.1.tgz", + "integrity": "sha512-w4LR6/bYZEuCs7SGr+M54oipk/UQKtiMadyOhW0PTwAtJ/Ai12QS77sLngEcfBx2q4H8ZBQucc9ktSA5sUGZWw==", + "funding": { + "url": "https://ko-fi.com/pixievoltno1" + }, + "peerDependencies": { + "svelte": "^3.2.1 || ^4.0.0-next.1 || ^5.0.0-next.94" + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", @@ -4252,9 +4280,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", + "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -4322,9 +4350,9 @@ } }, "node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { "node": ">=14" }, @@ -4332,10 +4360,22 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "bin": { "yaml": "bin.mjs" }, @@ -4382,7 +4422,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4417,9 +4456,9 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-check": { "version": "0.4.0", @@ -4446,9 +4485,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -4503,12 +4542,12 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz", + "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", + "esbuild": "^0.21.3", "postcss": "^8.4.38", "rollup": "^4.13.0" }, diff --git a/apps/settings/package.json b/apps/settings/package.json index f3ca661b9..56ec5553f 100644 --- a/apps/settings/package.json +++ b/apps/settings/package.json @@ -39,9 +39,10 @@ }, "type": "module", "dependencies": { - "@tauri-apps/api": "^1.6.0", + "@tauri-apps/api": "^1.5.6", "bits-ui": "^0.21.8", "clsx": "^2.1.1", + "svelte-french-toast": "^1.2.0", "tailwind-merge": "^2.3.0", "tailwind-variants": "^0.2.1" } diff --git a/apps/settings/src-tauri/Cargo.toml b/apps/settings/src-tauri/Cargo.toml index 615d7e938..4e35d332b 100644 --- a/apps/settings/src-tauri/Cargo.toml +++ b/apps/settings/src-tauri/Cargo.toml @@ -26,6 +26,10 @@ thiserror = "1.0.59" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } zbus = { version = "4.1.2", features = ["tokio"] } +upower = { path = "../../../commons/upower" } +keyring = "2.3.3" +users = "0.11.0" +uuid = "1.9.0" [features] # this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. diff --git a/apps/settings/src-tauri/src/constants.rs b/apps/settings/src-tauri/src/constants.rs new file mode 100644 index 000000000..5c833e3bd --- /dev/null +++ b/apps/settings/src-tauri/src/constants.rs @@ -0,0 +1 @@ +pub const SECRET_KEY : &str = "mechanix-shell"; \ No newline at end of file diff --git a/apps/settings/src-tauri/src/main.rs b/apps/settings/src-tauri/src/main.rs index 2179f7b83..bc3ecb13e 100644 --- a/apps/settings/src-tauri/src/main.rs +++ b/apps/settings/src-tauri/src/main.rs @@ -4,7 +4,9 @@ use std::{thread::JoinHandle, time::Duration}; use tauri::{Manager, Window}; +use upower::BatteryStatus; +mod constants; mod error; mod modules; @@ -19,13 +21,10 @@ struct Payload { message: String, } - fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![ + .invoke_handler(tauri::generate_handler![ modules::bluetooth::get_bluetooth_status, - - modules::wireless::get_wireless_status, modules::wireless::enable_wifi, modules::wireless::disable_wifi, @@ -35,9 +34,35 @@ fn main() { modules::wireless::get_known_networks, modules::wireless::connect_to_network, modules::wireless::connect_to_known_network, - - - + modules::wireless::disconnect_network, + modules::bluetooth::scan_bluetooth, + modules::bluetooth::enable_bluetooth, + modules::bluetooth::disable_bluetooth, + modules::bluetooth::connect_bluetooth_device, + modules::bluetooth::disconnect_bluetooth_device, + modules::display::get_brightness, + modules::display::set_brightness, + modules::sound::get_input_devices, + modules::sound::get_output_devices, + modules::sound::get_output_sound_value, + modules::sound::set_output_sound_value, + modules::sound::get_input_sound_value, + modules::sound::set_input_sound_value, + modules::sound::input_device_toggle_mute, + modules::sound::output_device_toggle_mute, + modules::battery::get_battery_percentage, + modules::battery::get_avilable_performance_modes, + modules::battery::get_current_performance_mode, + modules::battery::set_performance_mode, + modules::security::set_pin_secret, + modules::security::get_pin_secret, + modules::security::get_security_lock_status, + modules::security::change_pin, + modules::security::authenticate_pin, + modules::security::remove_pin_lock, + modules::appearance::get_available_wallpapers, + modules::appearance::get_applied_wallpaper, + modules::appearance::set_wallpaper, exit_app ]) .run(tauri::generate_context!()) diff --git a/apps/settings/src-tauri/src/modules/appearance/client.rs b/apps/settings/src-tauri/src/modules/appearance/client.rs new file mode 100644 index 000000000..1ef7ab832 --- /dev/null +++ b/apps/settings/src-tauri/src/modules/appearance/client.rs @@ -0,0 +1,45 @@ + +use tracing::info; +use zbus::{Connection, proxy , Result}; +use anyhow::{bail, Result as AnyhowResult}; + +#[proxy( + interface = "org.mechanix.services.Appearance", + default_service = "org.mechanix.services.Appearance", + default_path = "/org/mechanix/services/Appearance" +)] +trait AppearanceInterface { + async fn get_all_wallpapers(&self) -> Result>; + async fn get_wallpaper(&self) -> Result; + async fn set_wallpaper(&self, value: &str) -> Result<()>; +} + +pub struct Appearance; + +impl Appearance { + + pub async fn get_all_wallpapers() -> Result> { + println!("appearance::client::get_all_wallpapers()"); + let connection = Connection::system().await?; + let proxy = AppearanceInterfaceProxy::new(&connection).await?; + let mut reply = proxy.get_all_wallpapers().await?; + println!("get_all_wallpapers reply ====> {:?}", reply); + Ok(reply) + } + + pub async fn get_wallpaper() -> Result { + println!("appearance::client::get_wallpaper()"); + let connection = Connection::system().await?; + let proxy = AppearanceInterfaceProxy::new(&connection).await?; + let reply = proxy.get_wallpaper().await?; + Ok(reply) + } + + pub async fn set_wallpaper(value: &str) -> Result<()> { + println!("appearance::client::set_wallpaper()"); + let connection = Connection::system().await?; + let proxy = AppearanceInterfaceProxy::new(&connection).await?; + let reply = proxy.set_wallpaper(value).await?; + Ok(()) + } +} \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/appearance/mod.rs b/apps/settings/src-tauri/src/modules/appearance/mod.rs new file mode 100644 index 000000000..b4927065a --- /dev/null +++ b/apps/settings/src-tauri/src/modules/appearance/mod.rs @@ -0,0 +1,32 @@ +pub mod client; +use crate::error::Error; + +#[tauri::command] +pub async fn get_available_wallpapers() -> Result, Error> { + println!("appearance::mod::get_available_wallpapers"); + match client::Appearance::get_all_wallpapers().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn get_applied_wallpaper() -> Result { + println!("appearance::mod::get_applied_wallpaper"); + match client::Appearance::get_wallpaper().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn set_wallpaper(value: String) -> Result<(), Error> { + println!("appearance::mod::set_wallpaper {:?}", value); + match client::Appearance::set_wallpaper(&value).await { + Ok(v) => return Ok(v), + Err(e) => { + println!("appearance::mod::set_wallpaper::error() {:?}", e); + return Err(Error::Other(e.to_string())) + } + }; +} \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/battery/client.rs b/apps/settings/src-tauri/src/modules/battery/client.rs new file mode 100644 index 000000000..0a038a27c --- /dev/null +++ b/apps/settings/src-tauri/src/modules/battery/client.rs @@ -0,0 +1,82 @@ + +use tracing::info; +use zbus::{Connection, proxy , Result}; +use anyhow::{bail, Result as AnyhowResult}; + +#[proxy( + interface = "org.mechanix.services.Power", + default_service = "org.mechanix.services.Power", + default_path = "/org/mechanix/services/Power" +)] +trait PowerBusInterface { + async fn get_cpu_governor(&self) -> Result>; + async fn get_current_cpu_governor(&self) -> Result; + async fn set_cpu_governor(&self, value: &str) -> Result<()>; +} + +pub struct Power; + +impl Power { + + pub async fn get_all_performance_modes() -> Result> { + println!("battery::client::get_all_performance_modes()"); + let connection = Connection::system().await?; + let proxy = PowerBusInterfaceProxy::new(&connection).await?; + let mut reply = proxy.get_cpu_governor().await?; + println!("get_cpu_governor reply ====> {:?}", reply); + for mode in reply.iter_mut() { + if *mode == "performance" { + *mode = "High".to_string(); + } else if *mode == "powersave" { + *mode = "Low".to_string(); + } else if *mode == "conservative" { + *mode = "Balanced".to_string(); + } + } + Ok(reply) + } + + pub async fn get_battery_percentage() -> AnyhowResult { + println!("battery::client::get_battery_percentage()"); + let battery = match upower::get_battery().await { + Ok(battery) => battery, + Err(e) => bail!(e.to_string()), + }; + + let percentage: f64 = match battery.percentage().await { + Ok(p) => p, + Err(e) => bail!(e.to_string()), + }; + Ok(percentage) + } + + pub async fn get_current_performance_mode() -> Result { + println!("battery::client::get_current_performance_mode()"); + let connection = Connection::system().await?; + let proxy = PowerBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_current_cpu_governor().await?; + println!("get_current_performance_mode reply ====> {:?}", reply); + let result = match reply.as_str() { + "performance\n" => "High", + "powersave\n" => "Low", + "conservative\n" => "Balanced", + _=> "" + }; + Ok(result.to_string()) + } + + pub async fn set_cpu_governor(value: &str) -> Result<()> { + println!("battery::client::set_cpu_governor()"); + let connection = Connection::system().await?; + let proxy = PowerBusInterfaceProxy::new(&connection).await?; + let value_map = match value { + "High" => "performance", + "Low" => "powersave", + "Balanced" => "conservative", + _ => "", + }; + println!("value_map : {:?}", value_map.to_string()); + let reply = proxy.set_cpu_governor(value_map).await?; + Ok(()) + } +} \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/battery/mod.rs b/apps/settings/src-tauri/src/modules/battery/mod.rs new file mode 100644 index 000000000..183ffd574 --- /dev/null +++ b/apps/settings/src-tauri/src/modules/battery/mod.rs @@ -0,0 +1,42 @@ +pub mod client; +use crate::error::Error; + +#[tauri::command] +pub async fn get_battery_percentage() -> Result { + println!("battery::mod::get_battery_percentage"); + match client::Power::get_battery_percentage().await{ + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + } +} + +#[tauri::command] +pub async fn get_avilable_performance_modes() -> Result, Error> { + println!("battery::mod::get_performance_modes"); + match client::Power::get_all_performance_modes().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn get_current_performance_mode() -> Result { + println!("battery::mod::get_current_performance_mode"); + match client::Power::get_current_performance_mode().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + + +#[tauri::command] +pub async fn set_performance_mode(value: String) -> Result<(), Error> { + println!("battery::mod::set_performance_mode {:?}", value); + match client::Power::set_cpu_governor(&value).await { + Ok(v) => return Ok(v), + Err(e) => { + println!("battery::mod::set_performance_mode::error() {:?}", e); + return Err(Error::Other(e.to_string())) + } + }; +} diff --git a/apps/settings/src-tauri/src/modules/bluetooth/client.rs b/apps/settings/src-tauri/src/modules/bluetooth/client.rs index dc14c2e34..b5e96bdea 100644 --- a/apps/settings/src-tauri/src/modules/bluetooth/client.rs +++ b/apps/settings/src-tauri/src/modules/bluetooth/client.rs @@ -1,14 +1,9 @@ -use serde::{Deserialize, Serialize}; +use serde::Serialize; use tracing::info; use zbus::{proxy, zvariant::{ DeserializeDict, SerializeDict, Type}, Connection, Result}; -use tauri::{ - plugin::{Builder, TauriPlugin}, - Runtime, - }; - -#[derive(DeserializeDict, SerializeDict, Debug, Type, Clone, Default)] +#[derive(DeserializeDict, Debug, Type, Clone, Default, Serialize)] #[zvariant(signature = "a{sv}")] pub struct BluetoothScanResponse { pub address: String, @@ -22,14 +17,12 @@ pub struct BluetoothScanResponse { pub is_trusted: bool, } - -#[derive(DeserializeDict, SerializeDict, Type, Debug, Clone, Default)] +#[derive(DeserializeDict, Type, Debug, Clone, Default, Serialize)] #[zvariant(signature = "a{sv}")] pub struct BluetoothScanListResponse { pub bluetooth_devices: Vec, } - #[proxy( interface = "org.mechanix.services.Bluetooth", default_service = "org.mechanix.services.Bluetooth", @@ -40,6 +33,8 @@ trait Bluetooth { async fn enable(&self) -> Result<()>; async fn disable(&self) -> Result<()>; async fn status(&self) -> Result; + async fn connect(&self, address: &str) -> Result<()>; + async fn disconnect(&self, address: &str) -> Result<()>; } pub struct BluetoothService; @@ -56,22 +51,18 @@ impl BluetoothService { pub async fn enable_bluetooth() -> Result<()> { info!("In bluetooth enable status call:: "); let connection = Connection::system().await?; - let proxy = BluetoothProxy::new(&connection).await?; - let reply = proxy.enable().await?; - info!("enable_bluetooth reply: {:?}", reply); + println!("enable_bluetooth reply: {:?}", reply); Ok(reply) } pub async fn disable_bluetooth() -> Result<()> { info!("In bluetooth disable status call:: "); let connection = Connection::system().await?; - let proxy = BluetoothProxy::new(&connection).await?; - let reply = proxy.disable().await?; - info!("disable_bluetooth reply: {:?}", reply); + println!("disable_bluetooth reply: {:?}", reply); Ok(reply) } @@ -83,4 +74,21 @@ impl BluetoothService { } + pub async fn connect(address: &str) -> Result<()> { + let connection = Connection::system().await?; + let proxy = BluetoothProxy::new(&connection).await?; + let reply = proxy.connect(address).await?; + println!("connect reply: {:?}", reply); + Ok(reply) + } + + pub async fn disconnect(address: &str) -> Result<()> { + let connection = Connection::system().await?; + let proxy = BluetoothProxy::new(&connection).await?; + let reply = proxy.disconnect(address).await?; + println!("disconnect reply: {:?}", reply); + Ok(reply) + } + + } \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/bluetooth/mod.rs b/apps/settings/src-tauri/src/modules/bluetooth/mod.rs index 867520399..51f4eddc0 100644 --- a/apps/settings/src-tauri/src/modules/bluetooth/mod.rs +++ b/apps/settings/src-tauri/src/modules/bluetooth/mod.rs @@ -1,78 +1,80 @@ pub mod client; pub mod listener; use crate::error::Error; -use serde::Serialize; -use self::client::BluetoothScanResponse; - -#[derive(Debug, Serialize)] -pub struct BluetoothData { - pub status: i8, - pub available_devices: Vec -} +use self::client::BluetoothScanListResponse; #[tauri::command] -pub async fn get_bluetooth_status() -> Result { +pub async fn get_bluetooth_status() -> Result { println!("get_bluetooth_status...."); - let bluetooth_on = match client::BluetoothService::status().await { - Ok(v) => v, - Err(e) => return Err(Error::Other(e.to_string())), - }; - - if bluetooth_on == 0 { - return Ok(BluetoothData{ - status: 0, - available_devices: vec![] - }); - }; - - let scan_response = match client::BluetoothService::scan().await { - Ok(v) => v, - Err(e) => return Err(Error::Other(e.to_string())), + match client::BluetoothService::status().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) }; +} - println!("scan_response {:?}", scan_response); - if scan_response.bluetooth_devices.len() > 0 { - return Ok(BluetoothData{ - status: 1, - available_devices: scan_response.bluetooth_devices - }); - } else { - return Ok(BluetoothData{ - status: 0, - available_devices: vec![] - }); +#[tauri::command] +pub async fn scan_bluetooth() -> Result { + println!("scan_bluetooth...."); + match client::BluetoothService::scan().await { + Ok(v) => return Ok(v), + Err(e) => { + println!("bluetooth::scan_response error {:?} ", e); + return Err(Error::Other(e.to_string())) + }, }; } #[tauri::command] -async fn update_enable_bluetooth() -> Result<(), Error> { - println!("update_enable_bluetooth called...."); +pub async fn enable_bluetooth() -> Result<(), Error> { + println!("enable_bluetooth called...."); match client::BluetoothService::enable_bluetooth().await { - Ok(result) => { - println!("RESULT enable_bluetooth: {:?}", result); - Ok(()) - }, - Err(e) => { - println!("CHECK ERROR: {:?}", e); - Err(Error::Other(e.to_string())) - } + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) } } +// #[tauri::command] +// pub async fn enable_bluetooth() -> Result { +// println!("enable_bluetooth called...."); +// match client::BluetoothService::enable_bluetooth().await { +// Ok(v) => { +// // return Ok(v) +// println!("enable_bluetooth result: {:?}", v); +// return Ok(true); +// }, +// Err(e) => { +// println!("enable_bluetooth error: {:?}", e.to_string()); +// return Err(Error::Other(e.to_string())) +// } +// } +// } + #[tauri::command] -async fn update_disable_bluetooth() -> Result<(), Error> { - println!("update_disable_bluetooth called...."); +pub async fn disable_bluetooth() -> Result<(), Error> { + println!("disable_bluetooth called...."); match client::BluetoothService::disable_bluetooth().await { - Ok(result) => { - println!("RESULT disable_bluetooth: {:?}", result); - Ok(()) - }, - Err(e) => { - println!("CHECK ERROR: {:?}", e); - Err(Error::Other(e.to_string())) - } + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + } +} + +#[tauri::command] +pub async fn connect_bluetooth_device(address: &str) -> Result<(), Error> { + println!("connect_bluetooth_device called.... {:?}", address.to_owned()); + match client::BluetoothService::connect(address).await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + } +} + +#[tauri::command] +pub async fn disconnect_bluetooth_device(address: &str) -> Result<(), Error> { + println!("disconnect_bluetooth_device called.... {:?}", address.to_owned()); + match client::BluetoothService::disconnect(&address).await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) } } \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/display/client.rs b/apps/settings/src-tauri/src/modules/display/client.rs new file mode 100644 index 000000000..f79ce60d1 --- /dev/null +++ b/apps/settings/src-tauri/src/modules/display/client.rs @@ -0,0 +1,48 @@ +use serde::{Deserialize, Serialize}; +use zbus::{proxy, zvariant::{ DeserializeDict, SerializeDict, Type}, Connection, Result}; + +#[derive(Deserialize, Serialize, Type, PartialEq, Debug)] +pub struct NotificationEvent { + pub brightness_percentage: u8, +} + +#[proxy( + interface = "org.mechanix.services.Display", + default_service = "org.mechanix.services.Display", + default_path = "/org/mechanix/services/Display" +)] +trait DisplayBusInterface { + async fn get_brightness(&self) -> Result; + async fn set_brightness(&self, value: u8) -> Result<()>; + #[zbus(signal)] + async fn notification(&self, event: NotificationEvent) -> Result<()>; +} + +pub struct Display; + +impl Display { + pub async fn get_brightness_percentage() -> Result { + println!("get_brightness_percentage..."); + + let connection = Connection::system().await?; + let proxy : DisplayBusInterfaceProxy = DisplayBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_brightness().await?; + println!("get_brightness_percentage reply: {:?}", reply); + Ok(reply) + } + + pub async fn set_brightness_percentage(value: u8) -> Result<()> { + println!("set_brightness_percentage value: {:?}", value); + let connection = Connection::system().await?; + let proxy : DisplayBusInterfaceProxy = DisplayBusInterfaceProxy::new(&connection).await?; + let reply = proxy.set_brightness(value).await?; + Ok(reply) + } + + pub async fn get_notification_stream() -> Result> { + let connection = Connection::system().await?; + let proxy : DisplayBusInterfaceProxy = DisplayBusInterfaceProxy::new(&connection).await?; + let stream = proxy.receive_notification().await?; + Ok(stream) + } +} diff --git a/apps/settings/src-tauri/src/modules/display/mod.rs b/apps/settings/src-tauri/src/modules/display/mod.rs new file mode 100644 index 000000000..26f1475be --- /dev/null +++ b/apps/settings/src-tauri/src/modules/display/mod.rs @@ -0,0 +1,35 @@ +pub mod client; +use crate::error::Error; + +#[tauri::command] +pub async fn get_brightness() -> Result { + println!("get_brightness...."); + match client::Display::get_brightness_percentage().await { + Ok(v) => { + println!("get_brightness result: {:?} ", v.to_owned()); + return Ok(v) + }, + Err(e) => { + println!("get_brightness error: {:?} ", e.to_owned()); + + return Err(Error::Other(e.to_string())) + } + }; +} + + +#[tauri::command] +pub async fn set_brightness(value: u8) -> Result<(), Error> { + println!("set_brightness....{:?}", value.to_owned()); + match client::Display::set_brightness_percentage(value).await { + Ok(v) => { + println!("set_brightness result: {:?} ", v.to_owned()); + return Ok(v) + }, + Err(e) => { + println!("set_brightness error: {:?} ", e.to_owned()); + + return Err(Error::Other(e.to_string())) + } + }; +} \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/mod.rs b/apps/settings/src-tauri/src/modules/mod.rs index 17743a670..f51a5be63 100644 --- a/apps/settings/src-tauri/src/modules/mod.rs +++ b/apps/settings/src-tauri/src/modules/mod.rs @@ -1,2 +1,7 @@ +pub mod appearance; +pub mod battery; pub mod bluetooth; +pub mod display; +pub mod security; +pub mod sound; pub mod wireless; diff --git a/apps/settings/src-tauri/src/modules/security/client.rs b/apps/settings/src-tauri/src/modules/security/client.rs new file mode 100644 index 000000000..15e0d74f1 --- /dev/null +++ b/apps/settings/src-tauri/src/modules/security/client.rs @@ -0,0 +1,45 @@ +use zbus::{proxy, Connection, Result}; + +#[proxy( + interface = "org.mechanix.services.Security", + default_service = "org.mechanix.services.Security", + default_path = "/org/mechanix/services/Security" +)] +trait SecurityBusInterface { + async fn change_password(&self, old: String, secret: String, new: String) -> Result; + async fn is_password_set(&self) -> Result; + async fn authenticate_user(&self, password: String, secret: String) -> Result; +} + +pub struct Security; + +impl Security { + pub fn is_pin_enabled() -> Result { + let connection = zbus::blocking::Connection::system()?; + let proxy: std::result::Result = SecurityBusInterfaceProxyBlocking::new(&connection); + let reply = proxy?.is_password_set()?; + Ok(reply) + } + + pub async fn authenticate(password: String, secret: String) -> Result { + let connection = Connection::system().await?; + let proxy = SecurityBusInterfaceProxy::new(&connection).await?; + let reply = proxy.authenticate_user(password, secret).await?; + Ok(reply) + } + + pub fn change_password(old: String, secret: String, new: String) -> Result { + let connection = zbus::blocking::Connection::system()?; + let proxy = SecurityBusInterfaceProxyBlocking::new(&connection)?; + let reply = proxy.change_password(old, secret, new)?; + Ok(reply) + } + + pub fn remove_pin_lock(pin: String, secret: String) -> Result { + // let connection = zbus::blocking::Connection::system()?; + // let proxy: std::result::Result = SecurityBusInterfaceProxyBlocking::new(&connection); + // let reply = proxy?.remove_pin(pin, secret)?; + // Ok(reply) + Ok(true) + } +} diff --git a/apps/settings/src-tauri/src/modules/security/mod.rs b/apps/settings/src-tauri/src/modules/security/mod.rs new file mode 100644 index 000000000..5cfc85adb --- /dev/null +++ b/apps/settings/src-tauri/src/modules/security/mod.rs @@ -0,0 +1,138 @@ +pub mod client; +use std::string; + +use keyring::Entry; +use users::get_current_username; +use uuid::Uuid; + +use crate::constants; +use crate::error::Error; + +#[tauri::command] +pub fn set_pin_secret() -> Result { + println!("Calling::set_pin_secret()"); + match get_current_username() { + Some(uname) => { + println!("Running as user with name {:?}", uname); + let entry = Entry::new(&constants::SECRET_KEY, &(uname.to_string_lossy())).unwrap(); + + let secret: Uuid = Uuid::new_v4(); + let _ = entry.set_password(&(secret.to_string())); + println!("SET SECRET :: {:?}", secret.to_string()); + return Ok(secret.to_string()); + } + None => { + println!("The current user does not exist!"); + return Err(Error::Other("The current user does not exist!".to_string())); + } + }; +} + +#[tauri::command] +pub fn get_pin_secret() -> Result { + println!("Calling::Security::get_pin_secret()"); + + match get_current_username() { + Some(uname) => { + println!("Running as user with name {:?}", uname); + let mut entry = Entry::new(&constants::SECRET_KEY, &(uname.to_string_lossy())).unwrap(); + + let secret = entry.get_password().unwrap(); + println!("GET SECRET :: {:?}", secret); + return Ok(secret); + } + None => { + println!("The current user does not exist!"); + return Err(Error::Other("The current user does not exist!".to_string())); + } + }; +} + +#[tauri::command] +pub fn get_security_lock_status() -> Result { + println!("Calling::Security::get_security_lock_status"); + match client::Security::is_pin_enabled() { + Ok(v) => return Ok(v), + Err(e) => { + println!("ERROR:: {:?} ", e.to_string()); + if e.to_string().contains("Entry not found") { + return Ok(false); + } + return Err(Error::Other(e.to_string())); + } + }; +} + +#[tauri::command] +pub async fn authenticate_pin(pin: String) -> Result { + println!("Calling::Security::authenticate_pin() {:?} ", pin); + + let secret = match get_pin_secret() { + Ok(secret) => secret, + Err(e) => return Err(e), + }; + println!("Calling::Security::authenticate_pin()::get_pin_secret {:?} ", secret); + + match client::Security::authenticate(pin, secret).await { + Ok(v) => { + println!("authenticate result: {:?}", v); + return Ok(v) + }, + Err(e) => { + println!("authenticate error: {:?}", e.to_string()); + return Err(Error::Other(e.to_string())) + }, + }; +} + +#[tauri::command] +pub fn change_pin(old_pin: String, new_pin: String, set_new_secret: bool) -> Result { + println!("Calling::Security::change_pin() old pin {:?} and new_pin {:?} ", &old_pin,&new_pin); + let mut secret = String::from(""); + + if set_new_secret { + secret = match set_pin_secret() { + Ok(secret) => secret, + Err(e) => return Err(e), + }; + } + else { + secret = match get_pin_secret() { + Ok(secret) => secret, + Err(e) => return Err(e), + }; + } + + + println!("change_pin with secret {:?} ", &secret); + match client::Security::change_password(old_pin, secret, new_pin) { + Ok(v) => { + println!("change_password result: {:?}", v); + return Ok(v) + }, + Err(e) => { + println!("change_password error: {:?}", e.to_string()); + return Err(Error::Other(e.to_string())) + }, + }; + +} + +#[tauri::command] +pub fn remove_pin_lock(pin: String) -> Result { + println!("Calling::Security::remove_pin_lock"); + let mut secret = match get_pin_secret() { + Ok(secret) => secret, + Err(e) => return Err(e), + }; + match client::Security::remove_pin_lock(pin, secret) { + Ok(v) => return Ok(v), + Err(e) => { + println!("ERROR:: {:?} ", e.to_string()); + if e.to_string().contains("Entry not found") { + return Ok(false); + } + return Err(Error::Other(e.to_string())); + } + }; +} \ No newline at end of file diff --git a/apps/settings/src-tauri/src/modules/sound/client.rs b/apps/settings/src-tauri/src/modules/sound/client.rs new file mode 100644 index 000000000..bb1042a7b --- /dev/null +++ b/apps/settings/src-tauri/src/modules/sound/client.rs @@ -0,0 +1,119 @@ +use serde::{Deserialize, Serialize}; +use tracing::info; +use zbus::{ + proxy, + zvariant::{DeserializeDict, SerializeDict, Type}, + Connection, Result +}; +use std::{collections::HashMap, sync::Arc, thread, time::Duration}; + + +#[derive(Deserialize, Serialize, Type, PartialEq, Debug)] +pub struct NotificationEvent { + pub is_mute: bool, + pub volume_level: f64, +} + +#[derive(DeserializeDict, Serialize, Type, Debug)] +// `Type` treats `SinkInformationResponse` is an alias for `a{sv}`. +#[zvariant(signature = "a{sv}")] +pub struct SinkInformationResponse { + pub name: String, + pub description: String, + pub prop_list: HashMap, +} + +#[derive(DeserializeDict, Serialize, Type, Debug)] +// `Type` treats `SourceInformationResponse` is an alias for `a{sv}`. +#[zvariant(signature = "a{sv}")] +pub struct SourceInformationResponse { + pub name: String, + pub description: String, + pub prop_list: HashMap, +} + +#[proxy( + interface = "org.mechanix.services.Sound", + default_service = "org.mechanix.services.Sound", + default_path = "/org/mechanix/services/Sound" +)] +trait SoundBusInterface { + async fn get_output_device_volume(&self, device: String) -> Result; + async fn set_output_device_volume(&self, volume: f64, device: String) -> Result<()>; + async fn get_input_device_volume(&self, device: String) -> Result; + async fn set_input_device_volume(&self, volume: f64, device: String) -> Result<()>; + // #[zbus(signal)] + // async fn notification(&self, event: NotificationEvent) -> Result<()>; + async fn get_connected_input_devices(&self) -> Result>; + async fn get_connected_output_devices(&self) -> Result>; + async fn input_device_toggle_mute(&self, device: String) -> Result<()>; + async fn output_device_toggle_mute(&self, device: String) -> Result<()>; +} + +pub struct Sound; + +impl Sound { + pub async fn get_output_sound_percentage(device: String) -> Result { + println!("Sound proxy get_output_sound_percentage()"); + let connection = Connection::session().await?; + let proxy : SoundBusInterfaceProxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_output_device_volume(device).await?; + println!("get_output_sound_percentage reply: {:?}", reply); + Ok(reply) + } + + pub async fn set_output_sound_percentage(value: f64, device: String) -> Result<()> { + println!("Sound proxy set_output_sound_percentage() {:?}", value); + let connection = Connection::session().await?; + let proxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.set_output_device_volume(value, device).await?; + Ok(reply) + } + + pub async fn get_input_sound_percentage(device: String) -> Result { + println!("Sound proxy get_input_sound_percentage()"); + let connection = Connection::session().await?; + let proxy : SoundBusInterfaceProxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_input_device_volume(device).await?; + println!("get_input_sound_percentage reply: {:?}", reply); + Ok(reply) + } + + pub async fn set_input_sound_percentage(value: f64, device: String) -> Result<()> { + println!("Sound proxy set_input_sound_percentage() {:?}", value); + let connection = Connection::session().await?; + let proxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.set_input_device_volume(value, device).await?; + Ok(reply) + } + + pub async fn get_input_devices() -> Result> { + let connection = Connection::session().await?; + let proxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_connected_input_devices().await?; + Ok(reply) + } + + pub async fn get_output_devices() -> Result> { + let connection = Connection::session().await?; + let proxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.get_connected_output_devices().await?; + Ok(reply) + } + + pub async fn input_device_toggle_mute(device: String) -> Result<()> { + println!("modules::sound::input_device_toggle_mute()"); + let connection = Connection::session().await?; + let proxy : SoundBusInterfaceProxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.input_device_toggle_mute(device).await?; + Ok(reply) + } + + pub async fn output_device_toggle_mute(device: String) -> Result<()> { + println!("modules::sound::output_device_toggle_mute()"); + let connection = Connection::session().await?; + let proxy : SoundBusInterfaceProxy = SoundBusInterfaceProxy::new(&connection).await?; + let reply = proxy.output_device_toggle_mute(device).await?; + Ok(reply) + } +} diff --git a/apps/settings/src-tauri/src/modules/sound/mod.rs b/apps/settings/src-tauri/src/modules/sound/mod.rs new file mode 100644 index 000000000..34ccfc77f --- /dev/null +++ b/apps/settings/src-tauri/src/modules/sound/mod.rs @@ -0,0 +1,92 @@ +pub mod client; +use crate::error::Error; + +use self::client::{SinkInformationResponse, SourceInformationResponse}; + +#[tauri::command] +pub async fn get_output_sound_value(device: String) -> Result { + println!( "SoundService::get_output_sound_value() {:?} ", &device); + let sound = match client::Sound::get_output_sound_percentage(device).await { + Ok(v) => v, + Err(e) => return Err(Error::Other(e.to_string())) + }; + + Ok(sound as u8) +} + +#[tauri::command] +pub async fn set_output_sound_value(value: u8, device: String) -> Result<(), Error> { + println!("SoundService::set_output_sound_value() {:?} converted value {:?}", + value, + (value as f32) as u8 + ); + match client::Sound::set_output_sound_percentage(value as f64, device).await { + Ok(v) => v, + Err(e) => return Err(Error::Other(e.to_string())) + }; + + Ok(()) +} + + +#[tauri::command] +pub async fn get_input_sound_value(device: String) -> Result { + println!( "SoundService::get_input_sound_value() {:?} ", &device); + let sound = match client::Sound::get_input_sound_percentage(device).await { + Ok(v) => v, + Err(e) => return Err(Error::Other(e.to_string())) + }; + + Ok(sound as u8) +} + +#[tauri::command] +pub async fn set_input_sound_value(value: u8, device: String) -> Result<(), Error> { + println!("SoundService::set_input_sound_value() {:?} converted value {:?}", + value, + (value as f32) as u8 + ); + match client::Sound::set_input_sound_percentage(value as f64, device).await { + Ok(v) => v, + Err(e) => return Err(Error::Other(e.to_string())) + }; + + Ok(()) +} + + +#[tauri::command] +pub async fn get_input_devices() -> Result, Error> { + println!( "SoundService::get_input_devices()"); + match client::Sound::get_input_devices().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn get_output_devices() -> Result, Error> { + println!( "SoundService::get_output_devices()"); + match client::Sound::get_output_devices().await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn input_device_toggle_mute(device: String) -> Result<(), Error> { + println!( "SoundService::input_device_toggle_mute()"); + match client::Sound::input_device_toggle_mute(device).await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} + +#[tauri::command] +pub async fn output_device_toggle_mute(device: String) -> Result<(), Error> { + println!( "SoundService::output_device_toggle_mute()"); + match client::Sound::output_device_toggle_mute(device).await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())) + }; +} diff --git a/apps/settings/src-tauri/src/modules/wireless/client.rs b/apps/settings/src-tauri/src/modules/wireless/client.rs index 7aff67a92..b10107290 100644 --- a/apps/settings/src-tauri/src/modules/wireless/client.rs +++ b/apps/settings/src-tauri/src/modules/wireless/client.rs @@ -47,18 +47,12 @@ trait Wireless { async fn scan(&self) -> Result; async fn known_networks(&self) -> Result; async fn select_network(&self, network_id: &str) ->Result<()>; - async fn info(&self) -> Result; async fn status(&self) -> Result; async fn enable(&self) -> Result; async fn disable(&self) -> Result; async fn connect(&self, ssid: &str, password: &str) ->Result<()>; - - async fn disconnect(&self, ssid: &str) ->Result<()>; - - - - + async fn disconnect(&self, network_id: &str) ->Result<()>; } pub struct WirelessService; @@ -158,10 +152,9 @@ impl WirelessService { } pub async fn disconnect(value: &str) -> Result<()> { - let connection = Connection::system().await?; let proxy = WirelessProxy::new(&connection).await?; - let reply = proxy.disconnect(value).await?; + let reply = proxy.disconnect(value).await?; println!("get disconnect reply: {:?}", reply); Ok(reply) } diff --git a/apps/settings/src-tauri/src/modules/wireless/mod.rs b/apps/settings/src-tauri/src/modules/wireless/mod.rs index ea1018620..ccb377278 100644 --- a/apps/settings/src-tauri/src/modules/wireless/mod.rs +++ b/apps/settings/src-tauri/src/modules/wireless/mod.rs @@ -109,9 +109,18 @@ pub async fn connect_to_network(ssid: &str, password: &str) -> Result<(), Error> } #[tauri::command] -pub async fn connect_to_known_network(network_id: &str) -> Result<(), Error> { +pub async fn connect_to_known_network(network_ssid: &str) -> Result<(), Error> { println!("Calling::wireless::connect_to_known_network()"); - match WirelessService::connect_to_known_network(network_id).await { + match WirelessService::connect_to_known_network(network_ssid).await { + Ok(v) => return Ok(v), + Err(e) => return Err(Error::Other(e.to_string())), + }; +} + +#[tauri::command] +pub async fn disconnect_network(network_ssid: &str) -> Result<(), Error> { + println!("Calling::wireless::disconnect() ===> {:?} ", network_ssid); + match WirelessService::disconnect(network_ssid).await { Ok(v) => return Ok(v), Err(e) => return Err(Error::Other(e.to_string())), }; diff --git a/apps/settings/src-tauri/tauri.conf.json b/apps/settings/src-tauri/tauri.conf.json index d46d7291b..d601b4c6a 100644 --- a/apps/settings/src-tauri/tauri.conf.json +++ b/apps/settings/src-tauri/tauri.conf.json @@ -29,7 +29,7 @@ "icons/icon.icns", "icons/icon.ico" ], - "identifier": "com.tauri.dev", + "identifier": "so.mecha.dev", "longDescription": "", "macOS": { "entitlements": null, @@ -56,12 +56,12 @@ "windows": [ { "fullscreen": false, - "height": 600, + "height": 480, "resizable": true, "title": "settings-app", - "width": 800, - "decorations": false, - "transparent": true + "width": 480, + "transparent": true, + "decorations": true } ] } diff --git a/apps/settings/src/constants/index.ts b/apps/settings/src/constants/index.ts index 4aebad1ea..f13613832 100644 --- a/apps/settings/src/constants/index.ts +++ b/apps/settings/src/constants/index.ts @@ -3,6 +3,8 @@ export const SERVICE_LOG = "services::"; export const ERROR_LOG = "error::"; export const NETWORK_MODULE_LOG = "network::"; - +export const SETTINGS_MODULE_LOG = "settings::"; export const SET_INTERVAL_TIMER = 10000; + +export const SECURITY_PROTOCOLS = ["WPA-PSK", "WPA2-PSK", "WPA3-PSK"]; diff --git a/apps/settings/src/lib/assets/images/icons/audio.png b/apps/settings/src/lib/assets/images/icons/audio.png new file mode 100644 index 000000000..1bb746a8a Binary files /dev/null and b/apps/settings/src/lib/assets/images/icons/audio.png differ diff --git a/apps/settings/src/lib/assets/images/icons/no_audio.png b/apps/settings/src/lib/assets/images/icons/no_audio.png new file mode 100644 index 000000000..802c8c1a1 Binary files /dev/null and b/apps/settings/src/lib/assets/images/icons/no_audio.png differ diff --git a/apps/settings/src/lib/components/block-item.svelte b/apps/settings/src/lib/components/block-item.svelte index d6a659930..42dbeb821 100644 --- a/apps/settings/src/lib/components/block-item.svelte +++ b/apps/settings/src/lib/components/block-item.svelte @@ -1,17 +1,15 @@ -
- -
-

{title}

- - -
-
- {#if isBottomBorderVisible}
{/if} -
+ +
+

{title}

+ +
+
+{#if isBottomBorderVisible}
{/if} diff --git a/apps/settings/src/lib/components/icons.svelte b/apps/settings/src/lib/components/icons.svelte index de54c22b9..104b87cbd 100644 --- a/apps/settings/src/lib/components/icons.svelte +++ b/apps/settings/src/lib/components/icons.svelte @@ -3,7 +3,7 @@ export let width = '1rem'; export let height = '1rem'; export let focusable: string | number | null | undefined = undefined; - let icons = { + let icons: any = { delete: { box: 32, svg: `` @@ -12,10 +12,23 @@ box: 28, svg: `` }, + blue_check_no_fill: { + box: 24, + svg: `` + }, + old_blue_checked: { + box: 28, + svg: `` + }, blue_checked: { box: 28, svg: `` }, + blue_radio_fill: { + box: 24, + svg: ` +` + }, blue_tick: { box: 40, svg: `` @@ -28,7 +41,7 @@ box: 30, svg: `` }, - bluetooth: { + bluetooth_30: { box: 30, svg: `` }, @@ -40,7 +53,7 @@ box: 30, svg: `` }, - battery: { + battery_old: { box: 30, svg: ` ` @@ -79,71 +92,202 @@ }, spinner: { box: 28, - svg: `` + svg: ` + ` }, lock: { - box: 20, - svg: `` + box: 24, + svg: ` + +` }, square_info: { box: 28, - svg: `` - }, - addition: { - box: 40, - svg: `` + svg: `` }, empty_ring: { box: 28, svg: `` }, - network_box: { + tick: { + box: 39, + svg: `` + }, + trash: { + box: 60, + svg: ` + + + + + + +` + }, + volume_unmute: { + box: 32, + svg: ` + + + + + + + + +` + }, + volume_mute: { + box: 32, + svg: ` + + + + + + + +` + }, + warning: { box: 30, - svg: `` + svg: ` + +` + }, + backspace: { + box: 40, + svg: ` +` + }, + cancel: { + box: 40, + svg: `` + }, + back: { + box: 40, + svg: ` + + + + + + + +` + }, + wifi: { + box: 24, + svg: `` + }, + bluetooth: { + box: 24, + svg: `` + }, + battery: { + box: 24, + svg: ` + + + + + + + + + + + + + +` + }, + network_box: { + box: 24, + svg: ` + +` }, bluetooth_box: { - box: 30, - svg: `` + box: 24, + svg: `` }, brush_box: { - box: 30, - svg: `` + box: 24, + svg: `` }, appearance_box: { - box: 30, - svg: `` + box: 24, + svg: `` }, battery_box: { - box: 30, - svg: `` + box: 24, + svg: ` + + + + + + + + + + + + + +` }, sound_box: { - box: 30, - svg: `` + box: 24, + svg: `` }, security_box: { - box: 30, - svg: `` + box: 24, + svg: ` + +` }, - date_box: { - box: 30, - svg: `` + time_box: { + box: 24, + svg: `` }, language_box: { - box: 30, - svg: `` + box: 24, + svg: ` +` }, updates_box: { - box: 30, - svg: `` + box: 24, + svg: `` }, about_box: { - box: 30, - svg: `` + box: 24, + svg: ` +` + }, + left_arrow: { + box: 60, + svg: `` }, - tick:{ - box:39, - svg:`` + addition: { + box: 50, + svg: `` + }, + submit: { + box: 60, + svg: ` + + + + + + +` + }, + hide_show: { + bod: 26, + svg: `` } } as const; let displayIcon = icons[name]; @@ -155,5 +299,5 @@ {focusable} {width} {height} - viewBox="0 0 {displayIcon.box} {displayIcon.box}">{@html displayIcon.svg}{@html displayIcon.svg} diff --git a/apps/settings/src/lib/components/layout.svelte b/apps/settings/src/lib/components/layout.svelte index 5c9221852..aa8888639 100644 --- a/apps/settings/src/lib/components/layout.svelte +++ b/apps/settings/src/lib/components/layout.svelte @@ -1,14 +1,39 @@ -
-
-

{title}

-
+
+ {#if title} +
+

{title}

+ {#if loader} + + {:else} + + {/if} +
+ {:else if bold_text.length > 0} +
+

+ Confirm this code on
+ {' '} + + {bold_text.length > 15 + ? `'${bold_text.slice(0, 10)}...${bold_text.substring(bold_text.length - 1)}'` + : `'${bold_text}'`} + +  to connect +

+
+ {/if}
-
+
+ +
{#if $$slots.footer}