├── actix-surrealdb-api ├── .gitignore ├── src │ ├── prelude.rs │ ├── model.rs │ ├── error.rs │ ├── api.rs │ ├── main.rs │ └── db.rs ├── docker-compose.yml └── Cargo.toml ├── todo-tauri-desktop ├── .taurignore ├── src-tauri │ ├── build.rs │ ├── .gitignore │ ├── icons │ │ ├── 32x32.png │ │ ├── icon.icns │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── 128x128.png │ │ ├── 128x128@2x.png │ │ ├── StoreLogo.png │ │ ├── Square30x30Logo.png │ │ ├── Square44x44Logo.png │ │ ├── Square71x71Logo.png │ │ ├── Square89x89Logo.png │ │ ├── Square107x107Logo.png │ │ ├── Square142x142Logo.png │ │ ├── Square150x150Logo.png │ │ ├── Square284x284Logo.png │ │ └── Square310x310Logo.png │ ├── src │ │ └── main.rs │ ├── Cargo.toml │ └── tauri.conf.json ├── package.json ├── src │ ├── components │ │ ├── mod.rs │ │ ├── task_list.rs │ │ ├── task_form.rs │ │ └── task_item.rs │ ├── main.rs │ ├── model.rs │ ├── todo_api.rs │ ├── state.rs │ ├── controllers.rs │ ├── helpers.rs │ └── app.rs ├── .vscode │ ├── settings.json │ └── extensions.json ├── .gitignore ├── public │ ├── favicon │ │ └── app-icon.png │ ├── fonts │ │ └── Kanit-Regular.ttf │ ├── img │ │ └── task-done-flat.svg │ └── tailwind_input.css ├── index.html ├── README.md ├── Trunk.toml ├── tailwind.config.js └── Cargo.toml ├── todo-yew-web ├── .gitignore ├── src │ ├── components │ │ ├── mod.rs │ │ ├── task_list.rs │ │ ├── task_form.rs │ │ └── task_item.rs │ ├── main.rs │ ├── model.rs │ ├── todo_api.rs │ ├── state.rs │ ├── controllers.rs │ └── app.rs ├── package.json ├── public │ ├── icon │ │ └── favicon-256.png │ ├── fonts │ │ └── Kanit-Regular.ttf │ ├── tailwind_input.css │ └── img │ │ └── task-done-flat.svg ├── Cargo.toml ├── tailwind.config.js ├── index.html ├── Trunk.toml ├── Cargo.lock └── package-lock.json ├── LICENSE └── README.md /actix-surrealdb-api/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | main-old 3 | -------------------------------------------------------------------------------- /todo-tauri-desktop/.taurignore: -------------------------------------------------------------------------------- 1 | /src 2 | /public 3 | /Cargo.toml -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | tauri_build::build() 3 | } 4 | -------------------------------------------------------------------------------- /todo-yew-web/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | public/tailwind_output.css 3 | node_modules 4 | target 5 | **.swp 6 | -------------------------------------------------------------------------------- /todo-yew-web/src/components/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod task_form; 2 | pub mod task_item; 3 | pub mod task_list; 4 | -------------------------------------------------------------------------------- /todo-yew-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "tailwindcss": "^3.3.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /todo-tauri-desktop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "tailwindcss": "^3.3.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/components/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod task_form; 2 | pub mod task_item; 3 | pub mod task_list; 4 | -------------------------------------------------------------------------------- /todo-tauri-desktop/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "emmet.includeLanguages": { 3 | "rust": "html" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | -------------------------------------------------------------------------------- /todo-tauri-desktop/.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /target/ 3 | /Cargo.lock 4 | 5 | /public/tailwind_output.css 6 | /node_modules/ 7 | **.swp 8 | -------------------------------------------------------------------------------- /todo-tauri-desktop/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] 3 | } 4 | -------------------------------------------------------------------------------- /todo-yew-web/public/icon/favicon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-yew-web/public/icon/favicon-256.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/32x32.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/icon.icns -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/icon.ico -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/icon.png -------------------------------------------------------------------------------- /todo-yew-web/public/fonts/Kanit-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-yew-web/public/fonts/Kanit-Regular.ttf -------------------------------------------------------------------------------- /todo-tauri-desktop/public/favicon/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/public/favicon/app-icon.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/128x128.png -------------------------------------------------------------------------------- /todo-tauri-desktop/public/fonts/Kanit-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/public/fonts/Kanit-Regular.ttf -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/128x128@2x.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/StoreLogo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square30x30Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square30x30Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square44x44Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square71x71Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square71x71Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square89x89Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square89x89Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square107x107Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square107x107Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square142x142Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square142x142Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square150x150Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square284x284Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square284x284Logo.png -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/icons/Square310x310Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emarifer/rasty-stack-example/HEAD/todo-tauri-desktop/src-tauri/icons/Square310x310Logo.png -------------------------------------------------------------------------------- /actix-surrealdb-api/src/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Crate prelude 2 | 3 | // Re-export the crate Error 4 | pub use crate::error::Error; 5 | 6 | // Alias Result to be the crate Result. 7 | pub type Result = core::result::Result; 8 | -------------------------------------------------------------------------------- /todo-yew-web/src/main.rs: -------------------------------------------------------------------------------- 1 | mod app; 2 | mod components; 3 | mod controllers; 4 | mod model; 5 | mod state; 6 | mod todo_api; 7 | 8 | use app::App; 9 | 10 | fn main() { 11 | yew::Renderer::::new().render(); 12 | } 13 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/main.rs: -------------------------------------------------------------------------------- 1 | mod app; 2 | mod components; 3 | mod controllers; 4 | mod helpers; 5 | mod model; 6 | mod state; 7 | mod todo_api; 8 | 9 | use app::App; 10 | 11 | fn main() { 12 | yew::Renderer::::new().render(); 13 | } 14 | -------------------------------------------------------------------------------- /todo-tauri-desktop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tauri + Yew App 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /todo-tauri-desktop/README.md: -------------------------------------------------------------------------------- 1 | # Tauri + Yew 2 | 3 | This template should help get you started developing with Tauri and Yew. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). 8 | -------------------------------------------------------------------------------- /todo-yew-web/src/model.rs: -------------------------------------------------------------------------------- 1 | use chrono::{DateTime, Local}; 2 | use serde::Deserialize; 3 | 4 | #[derive(Clone, PartialEq, Deserialize)] 5 | pub struct Task { 6 | pub id: String, 7 | pub title: String, 8 | pub completed: bool, 9 | pub created_at: DateTime, 10 | } 11 | 12 | #[derive(Deserialize)] 13 | pub struct AffectedRows { 14 | pub rows_affected: u64, 15 | } 16 | -------------------------------------------------------------------------------- /todo-yew-web/public/tailwind_input.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* global styles */ 6 | 7 | @font-face { 8 | font-family: "Kanit"; 9 | font-weight: normal; 10 | src: url(fonts/Kanit-Regular.ttf) format("truetype"); 11 | } 12 | 13 | @layer base { 14 | body { 15 | @apply bg-primary p-5 text-cyan-50 font-kanit; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/model.rs: -------------------------------------------------------------------------------- 1 | use chrono::{DateTime, Local}; 2 | use serde::Deserialize; 3 | 4 | #[derive(Clone, PartialEq, Deserialize, Debug)] 5 | pub struct Task { 6 | pub id: String, 7 | pub title: String, 8 | pub completed: bool, 9 | pub created_at: DateTime, 10 | } 11 | 12 | #[derive(Deserialize)] 13 | pub struct AffectedRows { 14 | pub rows_affected: u64, 15 | } 16 | -------------------------------------------------------------------------------- /todo-tauri-desktop/Trunk.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "./index.html" 3 | 4 | [watch] 5 | ignore = ["./src-tauri"] 6 | 7 | [serve] 8 | address = "127.0.0.1" 9 | port = 1420 10 | open = false 11 | 12 | [[hooks]] 13 | stage = "pre_build" 14 | command = "npx" 15 | command_arguments = [ 16 | "tailwindcss", 17 | "-i", 18 | "public/tailwind_input.css", 19 | "-o", 20 | "public/tailwind_output.css", 21 | ] 22 | -------------------------------------------------------------------------------- /actix-surrealdb-api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | surrealdb: 4 | container_name: surrealdb 5 | image: surrealdb/surrealdb:latest 6 | # You can remove the memory option if you want to run the DB on disk 7 | command: start --user root --pass root file:///data/database.db 8 | ports: 9 | - '8000:8000' 10 | volumes: 11 | - /var/lib/docker/volumes/vol1:/data 12 | volumes: 13 | surrealdb: 14 | driver: local 15 | -------------------------------------------------------------------------------- /todo-yew-web/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todo_yew_web" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | chrono = { version = "0.4.24", features = ["serde"] } 10 | gloo-dialogs = "0.1.1" 11 | reqwasm = "0.5.0" 12 | serde = { version = "1.0.159", features = ["derive"] } 13 | wasm-bindgen-futures = "0.4.34" 14 | web-sys = "0.3.61" 15 | yew = { version = "0.20.0", features = ["csr"] } 16 | -------------------------------------------------------------------------------- /actix-surrealdb-api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actix-surrealdb-api" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | actix-web = { version = "4.3.1", features = ["macros"] } 10 | serde = { version = "1.0.159", features = ["derive"] } 11 | surrealdb = "1.0.0-beta.9" 12 | thiserror = "1.0.40" 13 | chrono = { version = "0.4.24", features = ["serde"] } 14 | futures = "0.3.28" 15 | actix-cors = "0.6.4" 16 | -------------------------------------------------------------------------------- /todo-yew-web/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const defaultTheme = require("tailwindcss/defaultTheme"); 3 | 4 | module.exports = { 5 | content: [ 6 | "./src/**/*.rs", 7 | "./index.html", 8 | "./src/**/*.html", 9 | "./src/**/*.css", 10 | ], 11 | theme: { 12 | extend: { 13 | colors: { 14 | primary: "#0f172a", 15 | }, 16 | fontFamily: { 17 | kanit: ["Kanit", ...defaultTheme.fontFamily.sans], 18 | }, 19 | }, 20 | }, 21 | plugins: [], 22 | }; 23 | -------------------------------------------------------------------------------- /todo-tauri-desktop/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const defaultTheme = require("tailwindcss/defaultTheme"); 3 | 4 | module.exports = { 5 | content: [ 6 | "./src/**/*.rs", 7 | "./index.html", 8 | "./src/**/*.html", 9 | "./src/**/*.css", 10 | ], 11 | theme: { 12 | extend: { 13 | colors: { 14 | primary: "#0f172a", 15 | }, 16 | fontFamily: { 17 | kanit: ["Kanit", ...defaultTheme.fontFamily.sans], 18 | }, 19 | }, 20 | }, 21 | plugins: [], 22 | }; 23 | -------------------------------------------------------------------------------- /actix-surrealdb-api/src/model.rs: -------------------------------------------------------------------------------- 1 | use chrono::{DateTime, Local}; 2 | use serde::{Deserialize, Serialize}; 3 | use surrealdb::sql::Thing; 4 | 5 | #[derive(Debug, Deserialize, Serialize)] 6 | pub struct Task { 7 | pub id: Option, 8 | pub title: String, 9 | pub completed: bool, 10 | pub created_at: DateTime, 11 | } 12 | 13 | #[derive(Debug, Deserialize, Serialize)] 14 | pub struct Record { 15 | #[allow(dead_code)] 16 | pub id: Thing, 17 | } 18 | 19 | #[derive(Debug, Serialize, Deserialize)] 20 | pub struct AffectedRows { 21 | pub rows_affected: u64, 22 | } 23 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/src/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr( 2 | all(not(debug_assertions), target_os = "windows"), 3 | windows_subsystem = "windows" 4 | )] 5 | 6 | // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command 7 | #[tauri::command] 8 | fn greet(name: &str) -> String { 9 | format!("Hello, {}! You've been greeted from Rust!", name) 10 | } 11 | 12 | fn main() { 13 | tauri::Builder::default() 14 | .invoke_handler(tauri::generate_handler![greet]) 15 | .run(tauri::generate_context!()) 16 | .expect("error while running tauri application"); 17 | } 18 | -------------------------------------------------------------------------------- /todo-tauri-desktop/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todo_tauri_desktop-ui" 3 | version = "0.0.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [dependencies] 8 | serde-wasm-bindgen = "0.4.3" 9 | js-sys = "0.3.59" 10 | serde = { version = "1.0.140", features = ["derive"] } 11 | wasm-bindgen = { version = "0.2.82", features = ["serde-serialize"] } 12 | wasm-bindgen-futures = "0.4.32" 13 | web-sys = "0.3.59" 14 | yew = { version="0.20.0", features = ["csr"] } 15 | chrono = { version = "0.4.24", features = ["serde"] } 16 | reqwasm = "0.5.0" 17 | 18 | [workspace] 19 | members = ["src-tauri"] 20 | -------------------------------------------------------------------------------- /todo-yew-web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Whattodo! 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /actix-surrealdb-api/src/error.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpResponse, ResponseError}; 2 | use thiserror::Error; 3 | 4 | #[derive(Error, Debug)] 5 | pub enum Error { 6 | /// For starter, to remove as code matures. 7 | #[error("Generic error: {0}")] 8 | Generic(String), 9 | 10 | #[error("database error")] 11 | Db, 12 | } 13 | 14 | impl ResponseError for Error { 15 | fn error_response(&self) -> HttpResponse { 16 | match self { 17 | Error::Db => HttpResponse::InternalServerError().body(self.to_string()), 18 | Error::Generic(msg) => HttpResponse::InternalServerError().body(msg.clone()), 19 | } 20 | } 21 | } 22 | 23 | impl From for Error { 24 | fn from(error: surrealdb::Error) -> Self { 25 | eprintln!("{error}"); 26 | Self::Db 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /todo-yew-web/Trunk.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # The index HTML file to drive the bundling process. 3 | target = "index.html" 4 | # Build in release mode. 5 | release = false 6 | # The output dir for all final assets. 7 | dist = "dist" 8 | # The public URL from which assets are to be served. 9 | public_url = "/" 10 | # Whether to include hash values in the output file names. 11 | filehash = true 12 | 13 | [serve] 14 | # The address to serve on. 15 | address = "127.0.0.1" 16 | # The port to serve on. 17 | port = 8081 18 | # Open a browser tab once the initial build is complete. 19 | open = false 20 | # Disable auto-reload of the web app. 21 | no_autoreload = false 22 | 23 | [[hooks]] 24 | stage = "pre_build" 25 | command = "npx" 26 | command_arguments = [ 27 | "tailwindcss", 28 | "-i", 29 | "public/tailwind_input.css", 30 | "-o", 31 | "public/tailwind_output.css", 32 | ] 33 | -------------------------------------------------------------------------------- /todo-yew-web/src/components/task_list.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use yew::{function_component, html, Callback, Html, Properties}; 3 | 4 | use super::task_item::TaskItem; 5 | use crate::model::Task; 6 | 7 | #[derive(Properties, PartialEq)] 8 | pub struct TaskListProps { 9 | pub tasks: VecDeque, 10 | pub deletetask: Callback, 11 | pub toggletask: Callback, 12 | } 13 | 14 | #[function_component(TaskList)] 15 | pub fn task_list( 16 | TaskListProps { 17 | tasks, 18 | deletetask, 19 | toggletask, 20 | }: &TaskListProps, 21 | ) -> Html { 22 | let tasks = tasks 23 | .iter() 24 | .map(|task| html!()) 25 | .collect::(); 26 | 27 | html! { 28 |
    29 | {tasks} 30 |
31 | } 32 | } 33 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/components/task_list.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use yew::{function_component, html, Callback, Html, Properties}; 3 | 4 | use super::task_item::TaskItem; 5 | use crate::model::Task; 6 | 7 | #[derive(Properties, PartialEq)] 8 | pub struct TaskListProps { 9 | pub tasks: VecDeque, 10 | pub deletetask: Callback, 11 | pub toggletask: Callback, 12 | } 13 | 14 | #[function_component(TaskList)] 15 | pub fn task_list( 16 | TaskListProps { 17 | tasks, 18 | deletetask, 19 | toggletask, 20 | }: &TaskListProps, 21 | ) -> Html { 22 | let tasks = tasks 23 | .iter() 24 | .map(|task| html!()) 25 | .collect::(); 26 | 27 | html! { 28 |
    29 | {tasks} 30 |
31 | } 32 | } 33 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todo_tauri_desktop" 3 | version = "0.0.0" 4 | description = "A Tauri App" 5 | authors = ["you"] 6 | license = "" 7 | repository = "" 8 | edition = "2021" 9 | rust-version = "1.57" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [build-dependencies] 14 | tauri-build = { version = "1.2", features = [] } 15 | 16 | [dependencies] 17 | serde_json = "1.0" 18 | serde = { version = "1.0", features = ["derive"] } 19 | tauri = { version = "1.2", features = ["dialog-all", "shell-open", "window-close"] } 20 | 21 | [features] 22 | # by default Tauri runs in production mode 23 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL 24 | default = ["custom-protocol"] 25 | # this feature is used used for production builds where `devPath` points to the filesystem 26 | # DO NOT remove this 27 | custom-protocol = ["tauri/custom-protocol"] 28 | -------------------------------------------------------------------------------- /todo-yew-web/src/todo_api.rs: -------------------------------------------------------------------------------- 1 | use reqwasm::{http::Request, Error}; 2 | use std::collections::VecDeque; 3 | 4 | use crate::model::*; 5 | 6 | #[allow(dead_code)] 7 | const BASE_URL: &str = "http://localhost:8080"; 8 | 9 | pub async fn fetch_tasks() -> Result, Error> { 10 | let response = Request::get(&format!("{BASE_URL}/todos")).send().await?; 11 | 12 | response.json().await 13 | } 14 | 15 | pub async fn create_task(title: &str) -> Result { 16 | let response = Request::post(&format!("{BASE_URL}/todo/{title}")) 17 | .send() 18 | .await?; 19 | 20 | response.json().await 21 | } 22 | 23 | pub async fn toggle_task(id: String) -> Result { 24 | let response = Request::patch(&format!("{BASE_URL}/todo/{id}")) 25 | .send() 26 | .await?; 27 | 28 | response.json().await 29 | } 30 | 31 | pub async fn delete_task(id: String) -> Result { 32 | let response = Request::delete(&format!("{BASE_URL}/todo/{id}")) 33 | .send() 34 | .await?; 35 | 36 | response.json().await 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Enrique Marín 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/todo_api.rs: -------------------------------------------------------------------------------- 1 | use reqwasm::{http::Request, Error}; 2 | use std::collections::VecDeque; 3 | 4 | // use crate::helpers::display_data; 5 | use crate::model::*; 6 | 7 | #[allow(dead_code)] 8 | const BASE_URL: &str = "http://localhost:8080"; 9 | 10 | pub async fn fetch_tasks() -> Result, Error> { 11 | // display_data(format!("{BASE_URL}/todos")); 12 | 13 | let response = Request::get(&format!("{BASE_URL}/todos")).send().await?; 14 | 15 | response.json().await 16 | } 17 | 18 | pub async fn create_task(title: &str) -> Result { 19 | let response = Request::post(&format!("{BASE_URL}/todo/{title}")) 20 | .send() 21 | .await?; 22 | 23 | response.json().await 24 | } 25 | 26 | pub async fn toggle_task(id: String) -> Result { 27 | let response = Request::patch(&format!("{BASE_URL}/todo/{id}")) 28 | .send() 29 | .await?; 30 | 31 | response.json().await 32 | } 33 | 34 | pub async fn delete_task(id: String) -> Result { 35 | let response = Request::delete(&format!("{BASE_URL}/todo/{id}")) 36 | .send() 37 | .await?; 38 | 39 | response.json().await 40 | } 41 | -------------------------------------------------------------------------------- /actix-surrealdb-api/src/api.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{ 2 | delete, 3 | get, 4 | patch, 5 | post, 6 | web::{Json, Path}, 7 | // HttpResponse, 8 | }; 9 | 10 | use crate::db::*; 11 | use crate::model::*; 12 | use crate::prelude::*; 13 | 14 | #[post("/todo/{title}")] 15 | pub async fn create(title: Path) -> Result> { 16 | let todo = add_task(title.into_inner()).await?; 17 | 18 | Ok(Json(todo)) 19 | 20 | // match todo_id { 21 | // Ok(id) => HttpResponse::Ok().json(id), 22 | // Err(err) => HttpResponse::InternalServerError().body(err.to_string()), 23 | // } 24 | } 25 | 26 | #[get("/todo/{id}")] 27 | pub async fn get(id: Path) -> Result> { 28 | let task = get_task(id.into_inner()).await?; 29 | 30 | Ok(Json(task)) 31 | } 32 | 33 | #[patch("/todo/{id}")] 34 | pub async fn update(id: Path) -> Result> { 35 | let updated = toggle_task(id.into_inner()).await?; 36 | 37 | Ok(Json(updated)) 38 | } 39 | 40 | #[delete("/todo/{id}")] 41 | pub async fn delete(id: Path) -> Result> { 42 | let deleted = delete_task(id.into_inner()).await?; 43 | 44 | Ok(Json(deleted)) 45 | } 46 | 47 | #[get("/todos")] 48 | pub async fn list() -> Result>> { 49 | let todos = get_all_tasks().await?; 50 | 51 | Ok(Json(todos)) 52 | } 53 | -------------------------------------------------------------------------------- /todo-yew-web/public/img/task-done-flat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /todo-tauri-desktop/public/img/task-done-flat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /todo-tauri-desktop/public/tailwind_input.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* global styles */ 6 | 7 | @font-face { 8 | font-family: "Kanit"; 9 | font-weight: normal; 10 | src: url(fonts/Kanit-Regular.ttf) format("truetype"); 11 | } 12 | 13 | @layer base { 14 | body { 15 | @apply bg-primary p-5 text-cyan-50 font-kanit; 16 | } 17 | } 18 | 19 | input[type="checkbox"] { 20 | cursor: pointer; 21 | background-color: transparent; 22 | background-image: url("data:image/svg+xml,%3csvg viewBox='2 2 12 12' fill='transparent' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); 23 | width: 1.5rem; 24 | height: 1.5rem; 25 | appearance: none; 26 | border: 2px solid #4b5563; 27 | border-radius: 4px; 28 | } 29 | 30 | input[type="checkbox"]:checked { 31 | background-color: #9333ea; 32 | background-image: url("data:image/svg+xml,%3csvg viewBox='2 2 12 12' fill='aliceblue' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); 33 | } 34 | 35 | /* 36 | * EL RENDERIZADO EN EL NAVEGADOR DE TAURI NO ES IGUAL QUE EN CHROME O FIREFOX, AL MENOS PARA ALGUNOS ELEMENTOS HTML 37 | * COMO INPUT CHECKBOX. EN CONSECUENCIA, ES NECESARIO UTLIZAR CÓDIGO CSS "DURO" EN LUGAR DE TAILWINDCSS. 38 | * (VER "Estilos CSS en campos checkbox" EN: https://desarrolloweb.com/articulos/estilos-css-campos-checkbox) 39 | */ 40 | -------------------------------------------------------------------------------- /todo-yew-web/src/state.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use std::rc::Rc; 3 | use yew::Reducible; 4 | 5 | use crate::model::Task; 6 | 7 | /// reducer's Action 8 | pub enum TaskAction { 9 | Set(VecDeque), 10 | Add(Task), 11 | Toggle(String), 12 | Delete(String), 13 | } 14 | 15 | /// reducer's State 16 | pub struct TaskState { 17 | pub tasks: VecDeque, 18 | } 19 | 20 | /// Implementation by default when starting the application 21 | impl Default for TaskState { 22 | fn default() -> Self { 23 | Self { 24 | tasks: VecDeque::from([]), 25 | } 26 | } 27 | } 28 | 29 | /// Implementation of Reducible (required for the reducer) 30 | impl Reducible for TaskState { 31 | /// Reducer Action Type 32 | type Action = TaskAction; 33 | 34 | fn reduce(self: Rc, action: Self::Action) -> Rc { 35 | let next_tasks = match action { 36 | TaskAction::Set(tasks) => tasks, 37 | TaskAction::Add(task) => { 38 | let mut tasks = self.tasks.clone(); 39 | tasks.push_front(task); 40 | tasks 41 | } 42 | TaskAction::Toggle(id) => { 43 | let mut tasks = self.tasks.clone(); 44 | let task = tasks.iter_mut().find(|task| task.id == id); 45 | if let Some(t) = task { 46 | t.completed = !t.completed; 47 | } 48 | tasks 49 | } 50 | TaskAction::Delete(id) => { 51 | let mut tasks = self.tasks.clone(); 52 | tasks.retain(|task| task.id != id); 53 | tasks 54 | } 55 | }; 56 | 57 | Self { tasks: next_tasks }.into() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/state.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use std::rc::Rc; 3 | use yew::Reducible; 4 | 5 | use crate::model::Task; 6 | 7 | /// reducer's Action 8 | pub enum TaskAction { 9 | Set(VecDeque), 10 | Add(Task), 11 | Toggle(String), 12 | Delete(String), 13 | } 14 | 15 | /// reducer's State 16 | pub struct TaskState { 17 | pub tasks: VecDeque, 18 | } 19 | 20 | /// Implementation by default when starting the application 21 | impl Default for TaskState { 22 | fn default() -> Self { 23 | Self { 24 | tasks: VecDeque::from([]), 25 | } 26 | } 27 | } 28 | 29 | /// Implementation of Reducible (required for the reducer) 30 | impl Reducible for TaskState { 31 | /// Reducer Action Type 32 | type Action = TaskAction; 33 | 34 | fn reduce(self: Rc, action: Self::Action) -> Rc { 35 | let next_tasks = match action { 36 | TaskAction::Set(tasks) => tasks, 37 | TaskAction::Add(task) => { 38 | let mut tasks = self.tasks.clone(); 39 | tasks.push_front(task); 40 | tasks 41 | } 42 | TaskAction::Toggle(id) => { 43 | let mut tasks = self.tasks.clone(); 44 | let task = tasks.iter_mut().find(|task| task.id == id); 45 | if let Some(t) = task { 46 | t.completed = !t.completed; 47 | } 48 | tasks 49 | } 50 | TaskAction::Delete(id) => { 51 | let mut tasks = self.tasks.clone(); 52 | tasks.retain(|task| task.id != id); 53 | tasks 54 | } 55 | }; 56 | 57 | Self { tasks: next_tasks }.into() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src-tauri/tauri.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "beforeDevCommand": "trunk serve", 4 | "beforeBuildCommand": "trunk build --release", 5 | "devPath": "http://localhost:1420", 6 | "distDir": "../dist", 7 | "withGlobalTauri": true 8 | }, 9 | "package": { 10 | "productName": "todo_tauri_desktop", 11 | "version": "0.0.0" 12 | }, 13 | "tauri": { 14 | "allowlist": { 15 | "dialog": { 16 | "all": true 17 | }, 18 | "window": { 19 | "all": false, 20 | "close": true 21 | }, 22 | "shell": { 23 | "all": false, 24 | "open": true 25 | } 26 | }, 27 | "bundle": { 28 | "active": true, 29 | "category": "DeveloperTool", 30 | "copyright": "", 31 | "deb": { 32 | "depends": [] 33 | }, 34 | "externalBin": [], 35 | "icon": [ 36 | "icons/32x32.png", 37 | "icons/128x128.png", 38 | "icons/128x128@2x.png", 39 | "icons/icon.icns", 40 | "icons/icon.ico" 41 | ], 42 | "identifier": "com.todo-tauri-desktop.emarifer.dev", 43 | "longDescription": "Desktop Task List application developed with Tauri and Yew", 44 | "macOS": { 45 | "entitlements": null, 46 | "exceptionDomain": "", 47 | "frameworks": [], 48 | "providerShortName": null, 49 | "signingIdentity": null 50 | }, 51 | "resources": [], 52 | "shortDescription": "Desktop Task List application", 53 | "targets": "all", 54 | "windows": { 55 | "certificateThumbprint": null, 56 | "digestAlgorithm": "sha256", 57 | "timestampUrl": "" 58 | } 59 | }, 60 | "security": { 61 | "csp": null 62 | }, 63 | "updater": { 64 | "active": false 65 | }, 66 | "windows": [ 67 | { 68 | "fullscreen": false, 69 | "height": 600, 70 | "resizable": true, 71 | "title": "Whattodo!", 72 | "width": 800 73 | } 74 | ] 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /todo-yew-web/src/controllers.rs: -------------------------------------------------------------------------------- 1 | use gloo_dialogs::alert; 2 | use wasm_bindgen_futures::spawn_local; 3 | use yew::UseReducerHandle; 4 | 5 | use crate::{state::*, todo_api::*}; 6 | 7 | pub struct TaskController { 8 | state: UseReducerHandle, 9 | } 10 | 11 | impl TaskController { 12 | pub fn new(state: UseReducerHandle) -> TaskController { 13 | TaskController { state } 14 | } 15 | 16 | pub fn init_tasks(&self) { 17 | let tasks = self.state.clone(); 18 | 19 | spawn_local(async move { 20 | let fetched_tasks = fetch_tasks().await; 21 | 22 | match fetched_tasks { 23 | Ok(ft) => tasks.dispatch(TaskAction::Set(ft)), 24 | Err(e) => alert(&e.to_string()), 25 | } 26 | }); 27 | } 28 | 29 | pub fn create_task(&self, title: String) { 30 | let tasks = self.state.clone(); 31 | 32 | spawn_local(async move { 33 | let response = create_task(&title).await; 34 | 35 | match response { 36 | Ok(task) => tasks.dispatch(TaskAction::Add(task)), 37 | Err(e) => alert(&e.to_string()), 38 | } 39 | }); 40 | } 41 | 42 | pub fn toggle_task(&self, id: String) { 43 | let tasks = self.state.clone(); 44 | 45 | spawn_local(async move { 46 | let response = toggle_task(id.clone()).await; 47 | 48 | match response { 49 | Ok(af) if af.rows_affected == 1 => tasks.dispatch(TaskAction::Toggle(id.clone())), 50 | Ok(_) => alert("Did not get a response"), 51 | Err(e) => alert(&e.to_string()), 52 | } 53 | }); 54 | } 55 | 56 | pub fn delete_task(&self, id: String) { 57 | let tasks = self.state.clone(); 58 | 59 | spawn_local(async move { 60 | let response = delete_task(id.clone()).await; 61 | 62 | match response { 63 | Ok(af) if af.rows_affected == 1 => tasks.dispatch(TaskAction::Delete(id.clone())), 64 | Ok(_) => alert("Did not get a response"), 65 | Err(e) => alert(&e.to_string()), 66 | } 67 | }); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/controllers.rs: -------------------------------------------------------------------------------- 1 | // use gloo_dialogs::alert; 2 | use wasm_bindgen_futures::spawn_local; 3 | use yew::UseReducerHandle; 4 | 5 | use crate::{helpers::show_message, state::*, todo_api::*}; 6 | 7 | pub struct TaskController { 8 | state: UseReducerHandle, 9 | } 10 | 11 | impl TaskController { 12 | pub fn new(state: UseReducerHandle) -> TaskController { 13 | TaskController { state } 14 | } 15 | 16 | pub fn init_tasks(&self) { 17 | let tasks = self.state.clone(); 18 | 19 | spawn_local(async move { 20 | let fetched_tasks = fetch_tasks().await; 21 | 22 | match fetched_tasks { 23 | Ok(ft) => tasks.dispatch(TaskAction::Set(ft)), 24 | Err(e) => show_message(e.to_string(), "error"), 25 | } 26 | }); 27 | } 28 | 29 | pub fn create_task(&self, title: String) { 30 | let tasks = self.state.clone(); 31 | 32 | spawn_local(async move { 33 | let response = create_task(&title).await; 34 | 35 | match response { 36 | Ok(task) => tasks.dispatch(TaskAction::Add(task)), 37 | Err(e) => show_message(e.to_string(), "error"), 38 | } 39 | }); 40 | } 41 | 42 | pub fn toggle_task(&self, id: String) { 43 | let tasks = self.state.clone(); 44 | 45 | spawn_local(async move { 46 | let response = toggle_task(id.clone()).await; 47 | 48 | match response { 49 | Ok(af) if af.rows_affected == 1 => tasks.dispatch(TaskAction::Toggle(id.clone())), 50 | Ok(_) => show_message("Did not get a response".to_string(), "error"), 51 | Err(e) => show_message(e.to_string(), "error"), 52 | } 53 | }); 54 | } 55 | 56 | pub fn delete_task(&self, id: String) { 57 | let tasks = self.state.clone(); 58 | 59 | spawn_local(async move { 60 | let response = delete_task(id.clone()).await; 61 | 62 | match response { 63 | Ok(af) if af.rows_affected == 1 => tasks.dispatch(TaskAction::Delete(id.clone())), 64 | Ok(_) => show_message("Did not get a response".to_string(), "error"), 65 | Err(e) => show_message(e.to_string(), "error"), 66 | } 67 | }); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /actix-surrealdb-api/src/main.rs: -------------------------------------------------------------------------------- 1 | mod api; 2 | mod db; 3 | mod error; 4 | mod model; 5 | mod prelude; 6 | 7 | use actix_cors::Cors; 8 | use actix_web::{App, HttpServer}; 9 | use surrealdb::engine::remote::ws::{Client, Ws}; 10 | use surrealdb::opt::auth::Root; 11 | use surrealdb::Surreal; 12 | 13 | use api::*; 14 | 15 | static DB: Surreal = Surreal::init(); 16 | 17 | const PORT: u16 = 8080; 18 | 19 | #[actix_web::main] 20 | async fn main() -> Result<(), Box> { 21 | DB.connect::("localhost:8000").await?; 22 | 23 | DB.signin(Root { 24 | username: "root", 25 | password: "root", 26 | }) 27 | .await?; 28 | 29 | DB.use_ns("namespace").use_db("database").await?; 30 | 31 | println!("✅ Database connected successfully!!"); 32 | 33 | println!("✅ Server running at http://localhost:{PORT}"); 34 | 35 | HttpServer::new(|| { 36 | let cors = Cors::default() 37 | .allow_any_origin() 38 | .allowed_methods(vec!["GET", "POST", "PATCH", "DELETE"]) 39 | .send_wildcard(); 40 | 41 | App::new() 42 | .wrap(cors) 43 | .service(create) 44 | .service(get) 45 | .service(update) 46 | .service(delete) 47 | .service(list) 48 | }) 49 | .bind(("localhost", PORT))? 50 | .run() 51 | .await?; 52 | 53 | Ok(()) 54 | } 55 | 56 | /* 57 | * ARRANCAR UN CONTENEDOR DOCKER DE SURREALDB CON UN FICHERO docker-compose.yml: 58 | * sudo docker compose up -d 59 | * 60 | * ENTRAR EN LA CLI DE SURREALDB EN EL CONTENEDOR CREADO: 61 | * sudo docker exec -it surrealdb /surreal sql -c http://localhost:8000 -u root -p root --ns namespace --db database --pretty 62 | * 63 | * VER SI EL CONTENEDOR DOCKER ESTÁ INICIADO: 64 | * sudo docker ps (CON EL FLAG --a SE LISTAN TODOS LOS CONTENEDORES, ACTIVOS Y NO ACTIVOS) 65 | * 66 | * DETENER EL CONTENEDOR DE DOCKER: 67 | * sudo docker stop surrealdb 68 | * 69 | * VOLVER A INICIAR EL CONTENEDOR DE DOCKER: 70 | * sudo docker start surrealdb 71 | */ 72 | 73 | /* 74 | * CORS EN ACTIX-WEB. VER: 75 | * https://stackoverflow.com/questions/73098788/access-control-allow-origin-missing-using-actix-web 76 | * https://github.com/actix/examples/blob/master/cors/backend/src/main.rs 77 | * https://docs.rs/actix-cors/0.6.4/actix_cors/ 78 | * https://github.com/actix/actix-extras/blob/master/actix-cors/examples/cors.rs 79 | */ 80 | -------------------------------------------------------------------------------- /todo-yew-web/src/components/task_form.rs: -------------------------------------------------------------------------------- 1 | use gloo_dialogs::alert; 2 | use web_sys::HtmlInputElement; 3 | use yew::{ 4 | function_component, html, use_effect, use_node_ref, Callback, Html, MouseEvent, Properties, 5 | }; 6 | 7 | #[derive(Properties, PartialEq)] 8 | pub struct TaskFormProps { 9 | pub createtask: Callback, 10 | } 11 | 12 | #[function_component(TaskForm)] 13 | pub fn task_form(props: &TaskFormProps) -> Html { 14 | let input_ref = use_node_ref(); 15 | 16 | let handle_click = { 17 | let input_ref = input_ref.clone(); 18 | let on_create_task = props.createtask.clone(); 19 | 20 | Callback::from(move |_e: MouseEvent| { 21 | if let Some(input) = input_ref.cast::() { 22 | let title = input.value(); 23 | 24 | if title.is_empty() { 25 | alert("This field can not be blank"); 26 | return; 27 | } 28 | 29 | on_create_task.emit(input.value()); 30 | // Reset the input 31 | input.set_value(""); 32 | } 33 | }) 34 | }; 35 | 36 | { 37 | let input_ref = input_ref.clone(); 38 | 39 | use_effect(move || { 40 | if let Some(input) = input_ref.cast::() { 41 | input.focus().unwrap(); 42 | } 43 | }); 44 | } 45 | 46 | html! { 47 |
48 | 49 | 50 |
51 | 52 |
53 | 59 | 60 | 66 |
67 |
68 | } 69 | } 70 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/components/task_form.rs: -------------------------------------------------------------------------------- 1 | // use gloo_dialogs::alert; 2 | use web_sys::HtmlInputElement; 3 | use yew::{ 4 | function_component, html, use_effect, use_node_ref, Callback, Html, MouseEvent, Properties, 5 | }; 6 | 7 | use crate::helpers::show_message; 8 | 9 | #[derive(Properties, PartialEq)] 10 | pub struct TaskFormProps { 11 | pub createtask: Callback, 12 | } 13 | 14 | #[function_component(TaskForm)] 15 | pub fn task_form(props: &TaskFormProps) -> Html { 16 | let input_ref = use_node_ref(); 17 | 18 | let handle_click = { 19 | let input_ref = input_ref.clone(); 20 | let on_create_task = props.createtask.clone(); 21 | 22 | Callback::from(move |_e: MouseEvent| { 23 | if let Some(input) = input_ref.cast::() { 24 | let title = input.value(); 25 | 26 | if title.is_empty() { 27 | show_message("This field can not be blank".to_string(), "warning"); 28 | return; 29 | } 30 | 31 | on_create_task.emit(input.value()); 32 | // Reset the input 33 | input.set_value(""); 34 | } 35 | }) 36 | }; 37 | 38 | { 39 | let input_ref = input_ref.clone(); 40 | 41 | use_effect(move || { 42 | if let Some(input) = input_ref.cast::() { 43 | input.focus().unwrap(); 44 | } 45 | }); 46 | } 47 | 48 | html! { 49 |
50 | 51 | 52 |
53 | 54 |
55 | 61 | 62 | 68 |
69 |
70 | } 71 | } 72 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/helpers.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use serde_wasm_bindgen::to_value; 3 | use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; 4 | use wasm_bindgen_futures::spawn_local; 5 | use yew::KeyboardEvent; 6 | 7 | // use crate::model::Task; 8 | 9 | #[wasm_bindgen] 10 | extern "C" { 11 | // #[wasm_bindgen(js_namespace = ["window", "__TAURI__", "http"], catch)] 12 | // async fn fetch(url: &str, args: JsValue) -> Result; 13 | 14 | #[wasm_bindgen(js_namespace = ["window", "__TAURI__", "dialog"])] 15 | async fn message(content: &str, args: JsValue) -> JsValue; 16 | 17 | #[wasm_bindgen(js_namespace = ["window", "__TAURI__", "window.appWindow"])] 18 | async fn close() -> JsValue; 19 | 20 | #[wasm_bindgen(js_namespace = console)] 21 | fn log(s: &str); 22 | 23 | } 24 | 25 | // #[derive(Serialize, Deserialize)] 26 | // struct FetchArgs<'a> { 27 | // method: &'a str, 28 | // timeout: u64, 29 | // } 30 | // 31 | // pub fn display_data(url: String) { 32 | // spawn_local(async move { 33 | // let todos = fetch( 34 | // url.as_str(), 35 | // to_value(&FetchArgs { 36 | // method: "GET", 37 | // timeout: 30, 38 | // }) 39 | // .unwrap(), 40 | // ) 41 | // .await; 42 | // 43 | // match todos { 44 | // Ok(result_ok) => { 45 | // let res = result_ok.clone(); 46 | // // let res2 = result_ok.clone(); 47 | // log(&format!("{:?}", from_value::>(res).unwrap())); 48 | // // data.set(Some(from_value::(res2).unwrap())); 49 | // } 50 | // Err(result_err) => { 51 | // log(&result_err.as_string().unwrap()); 52 | // // show_message(&result_err.as_string().unwrap(), "error"); 53 | // } 54 | // } 55 | // }); 56 | // } 57 | 58 | #[derive(Serialize, Deserialize)] 59 | struct MessageArgs<'a> { 60 | title: &'a str, 61 | #[serde(rename = "type")] 62 | kind: &'a str, 63 | } 64 | 65 | pub fn onclose(e: KeyboardEvent) { 66 | if e.ctrl_key() && e.key() == "q".to_string() { 67 | spawn_local(async { 68 | close().await; 69 | }) 70 | } 71 | } 72 | 73 | pub fn show_message(content: String, kind: &str) { 74 | // let content = content.to_string(); 75 | let kind = kind.to_string(); 76 | spawn_local(async move { 77 | message( 78 | &content, 79 | to_value(&MessageArgs { 80 | title: "Todo Tauri Desktop", 81 | kind: &kind, 82 | }) 83 | .unwrap(), 84 | ) 85 | .await; 86 | }); 87 | } 88 | -------------------------------------------------------------------------------- /actix-surrealdb-api/src/db.rs: -------------------------------------------------------------------------------- 1 | use chrono::offset::Local; 2 | 3 | use crate::model::*; 4 | use crate::prelude::*; 5 | use crate::DB; 6 | 7 | #[allow(dead_code)] 8 | const TASK: &str = "task"; 9 | 10 | pub async fn add_task(title: String) -> Result { 11 | let created: Task = DB 12 | .create(TASK) 13 | .content(Task { 14 | id: None, 15 | title, 16 | completed: false, 17 | created_at: Local::now(), 18 | }) 19 | .await?; 20 | 21 | Ok(created) 22 | } 23 | 24 | pub async fn get_task(id: String) -> Result { 25 | let th = id.split_once(":").unwrap(); 26 | let rec: Task = DB.select(th).await?; 27 | 28 | Ok(rec) 29 | } 30 | 31 | pub async fn delete_task(id: String) -> Result { 32 | let th = id.split_once(":").unwrap(); 33 | let _rec: Record = DB.delete(th).await?; 34 | 35 | Ok(AffectedRows { rows_affected: 1 }) 36 | } 37 | 38 | pub async fn toggle_task(id: String) -> Result { 39 | let (tb, id) = id.split_once(":").unwrap(); 40 | let sql = 41 | "UPDATE type::thing($tb, $id) SET completed = function() { return !this.completed; };"; 42 | 43 | let mut response = DB.query(sql).bind(("tb", tb)).bind(("id", id)).await?; 44 | 45 | let _task_updated = response 46 | .take::>(0)? 47 | .into_iter() 48 | .next() 49 | .ok_or(Error::Generic("Failed to update record".into()))?; 50 | 51 | Ok(AffectedRows { rows_affected: 1 }) 52 | } 53 | 54 | pub async fn get_all_tasks() -> Result> { 55 | // let tasks: Vec = DB.select(TASK).await?; 56 | 57 | // Ok(tasks) 58 | let sql = "SELECT * FROM type::table($table) ORDER BY created_at DESC;"; 59 | 60 | let mut response = DB.query(sql).bind(("table", TASK)).await?; 61 | 62 | let tasks: Vec = response.take(0)?; 63 | 64 | Ok(tasks) 65 | } 66 | 67 | /* 68 | * https://surrealdb.com/docs/surrealql/functions/type#thing 69 | * https://surrealdb.com/docs/surrealql/functions/script 70 | * https://stackoverflow.com/questions/36876570/return-first-item-of-vector 71 | * https://stackoverflow.com/questions/57707966/how-to-get-timestamp-of-the-current-date-and-time-in-rust 72 | */ 73 | 74 | /* 75 | * RAZÓN POR LA QUE USAR EL VERBO "PATCH" Y NO "PUT". VER: 76 | * https://www.abstractapi.com/guides/put-vs-patch 77 | * https://www.baeldung.com/cs/http-put-vs-patch 78 | * https://github.com/letsgetrusty/rsty-stack-example/tree/main/todo_api 79 | * https://www.google.com/search?q=difference+between+patch+and+put&oq=dif&aqs=chrome.0.69i59j69i57j35i39j69i60l2j69i65l3.2889j0j7&sourceid=chrome&ie=UTF-8 80 | * 81 | * SOBRE ok_or. VER: 82 | * Is there a way to simplify converting an Option into a Result without a macro? 83 | * https://stackoverflow.com/questions/37890405/is-there-a-way-to-simplify-converting-an-option-into-a-result-without-a-macro 84 | */ 85 | -------------------------------------------------------------------------------- /todo-yew-web/src/components/task_item.rs: -------------------------------------------------------------------------------- 1 | use chrono::Timelike; 2 | use yew::{classes, function_component, html, Callback, Event, Html, MouseEvent, Properties}; 3 | 4 | use crate::model::Task; 5 | 6 | #[derive(Properties, PartialEq)] 7 | pub struct TaskItemProps { 8 | pub task: Task, 9 | pub deletetask: Callback, 10 | pub toggletask: Callback, 11 | } 12 | 13 | #[function_component(TaskItem)] 14 | pub fn task_item( 15 | TaskItemProps { 16 | task, 17 | deletetask, 18 | toggletask, 19 | }: &TaskItemProps, 20 | ) -> Html { 21 | let date = task.created_at.date_naive().format("%d-%m-%Y"); 22 | 23 | let time_and_date = &format!( 24 | "{:02}:{:02} • {}", 25 | task.created_at.hour(), 26 | task.created_at.minute(), 27 | date 28 | ); 29 | 30 | let label_style = "w-full p-3 ml-2 text-lg truncate"; 31 | 32 | let completed_task = match task.completed { 33 | true => Some("text-gray-600 line-through"), 34 | false => None, 35 | }; 36 | 37 | let handle_click = { 38 | let task = task.clone(); 39 | let on_delete_task = deletetask.clone(); 40 | 41 | move |_e: MouseEvent| on_delete_task.emit(task.id.clone()) 42 | }; 43 | 44 | let handle_toggle = { 45 | let task = task.clone(); 46 | let on_toggle_task = toggletask.clone(); 47 | 48 | move |_e: Event| on_toggle_task.emit(task.id.clone()) 49 | }; 50 | 51 | html! { 52 |
  • 53 |
    54 |
    55 | 60 | 61 | 66 |
    67 | 68 |
    69 |

    {time_and_date}

    70 | 78 |
    79 |
    80 |
  • 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/components/task_item.rs: -------------------------------------------------------------------------------- 1 | use chrono::Timelike; 2 | use yew::{classes, function_component, html, Callback, Event, Html, MouseEvent, Properties}; 3 | 4 | use crate::model::Task; 5 | 6 | #[derive(Properties, PartialEq)] 7 | pub struct TaskItemProps { 8 | pub task: Task, 9 | pub deletetask: Callback, 10 | pub toggletask: Callback, 11 | } 12 | 13 | #[function_component(TaskItem)] 14 | pub fn task_item( 15 | TaskItemProps { 16 | task, 17 | deletetask, 18 | toggletask, 19 | }: &TaskItemProps, 20 | ) -> Html { 21 | let date = task.created_at.date_naive().format("%d-%m-%Y"); 22 | 23 | let time_and_date = &format!( 24 | "{:02}:{:02} • {}", 25 | task.created_at.hour(), 26 | task.created_at.minute(), 27 | date 28 | ); 29 | 30 | let label_style = "w-full p-3 ml-2 text-lg truncate"; 31 | 32 | let completed_task = match task.completed { 33 | true => Some("text-gray-600 line-through"), 34 | false => None, 35 | }; 36 | 37 | let handle_click = { 38 | let task = task.clone(); 39 | let on_delete_task = deletetask.clone(); 40 | 41 | move |_e: MouseEvent| on_delete_task.emit(task.id.clone()) 42 | }; 43 | 44 | let handle_toggle = { 45 | let task = task.clone(); 46 | let on_toggle_task = toggletask.clone(); 47 | 48 | move |_e: Event| on_toggle_task.emit(task.id.clone()) 49 | }; 50 | 51 | html! { 52 |
  • 53 |
    54 |
    55 | 60 | 61 | 66 |
    67 | 68 |
    69 |

    {time_and_date}

    70 | 78 |
    79 |
    80 |
  • 81 | } 82 | } 83 | 84 | /* 85 | * EL RENDERIZADO EN EL NAVEGADOR DE TAURI NO ES IGUAL QUE EN CHROME O FIREFOX, AL MENOS PARA ALGUNOS ELEMENTOS HTML 86 | * COMO INPUT CHECKBOX. EN CONSECUENCIA, ES NECESARIO UTLIZAR CÓDIGO CSS "DURO" EN LUGAR DE TAILWINDCSS. 87 | * (VER "Estilos CSS en campos checkbox" EN: https://desarrolloweb.com/articulos/estilos-css-campos-checkbox) 88 | */ 89 | -------------------------------------------------------------------------------- /todo-yew-web/src/app.rs: -------------------------------------------------------------------------------- 1 | use chrono::{offset::Local, Datelike}; 2 | use std::rc::Rc; 3 | use yew::{function_component, html, use_effect_with_deps, use_reducer, Callback, Html}; 4 | 5 | use crate::{ 6 | components::{task_form::TaskForm, task_list::TaskList}, 7 | controllers::*, 8 | state::TaskState, 9 | }; 10 | 11 | #[function_component(App)] 12 | pub fn app() -> Html { 13 | let tasks = use_reducer(TaskState::default); 14 | let task_controller = Rc::new(TaskController::new(tasks.clone())); 15 | 16 | // Get all tasks on app startup 17 | { 18 | let task_controller = task_controller.clone(); 19 | 20 | use_effect_with_deps( 21 | move |_| { 22 | task_controller.init_tasks(); 23 | || {} // return empty destructor closure (cleanup use_effect) 24 | }, 25 | (), 26 | ); // only call on first render 27 | } 28 | 29 | let on_create_task = { 30 | let task_controller = task_controller.clone(); 31 | 32 | Callback::from(move |title: String| task_controller.create_task(title)) 33 | }; 34 | 35 | let on_delete_task = { 36 | let task_controller = task_controller.clone(); 37 | 38 | Callback::from(move |id: String| task_controller.delete_task(id)) 39 | }; 40 | 41 | let on_toggle_task = { 42 | let task_controller = task_controller.clone(); 43 | 44 | Callback::from(move |id: String| task_controller.toggle_task(id)) 45 | }; 46 | 47 | html! { 48 |
    49 |
    50 |

    {"Whattodo!"}

    51 | 52 | Todo App logo 53 | 54 | 55 |
    56 | 57 | 58 |
    59 |

    {"Todo"}

    60 | 61 |
    62 | 63 | 64 |
    65 | 66 | 75 |
    76 | } 77 | } 78 | 79 | /* 80 | * ARRANCAR UN CONTENEDOR DOCKER DE SURREALDB CON UN FICHERO docker-compose.yml: 81 | * sudo docker compose up -d 82 | * 83 | * ENTRAR EN LA CLI DE SURREALDB EN EL CONTENEDOR CREADO: 84 | * sudo docker exec -it surrealdb /surreal sql -c http://localhost:8000 -u root -p root --ns namespace --db database --pretty 85 | * 86 | * VER SI EL CONTENEDOR DOCKER ESTÁ INICIADO: 87 | * sudo docker ps (CON EL FLAG --a SE LISTAN TODOS LOS CONTENEDORES, ACTIVOS Y NO ACTIVOS) 88 | * 89 | * DETENER EL CONTENEDOR DE DOCKER: 90 | * sudo docker stop surrealdb 91 | * 92 | * VOLVER A INICIAR EL CONTENEDOR DE DOCKER: 93 | * sudo docker start surrealdb 94 | */ 95 | 96 | /* 97 | * https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html 98 | * https://freeiconshop.com/ 99 | * https://tailwindcss.com/docs/accent-color 100 | * https://docs.rs/yew/0.20.0/yew/functional/fn.use_reducer.html 101 | * https://flowbite.com/docs/forms/checkbox/#bordered 102 | */ 103 | -------------------------------------------------------------------------------- /todo-tauri-desktop/src/app.rs: -------------------------------------------------------------------------------- 1 | use chrono::{offset::Local, Datelike}; 2 | use std::rc::Rc; 3 | use yew::{ 4 | function_component, html, use_effect_with_deps, use_reducer, Callback, Html, KeyboardEvent, 5 | }; 6 | 7 | use crate::{ 8 | components::{task_form::TaskForm, task_list::TaskList}, 9 | controllers::*, 10 | helpers::onclose, 11 | state::TaskState, 12 | }; 13 | 14 | #[function_component(App)] 15 | pub fn app() -> Html { 16 | let tasks = use_reducer(TaskState::default); 17 | let task_controller = Rc::new(TaskController::new(tasks.clone())); 18 | 19 | // Get all tasks on app startup 20 | { 21 | let task_controller = task_controller.clone(); 22 | 23 | use_effect_with_deps( 24 | move |_| { 25 | task_controller.init_tasks(); 26 | || {} // return empty destructor closure (cleanup use_effect) 27 | }, 28 | (), 29 | ); // only call on first render 30 | } 31 | 32 | let on_create_task = { 33 | let task_controller = task_controller.clone(); 34 | 35 | Callback::from(move |title: String| task_controller.create_task(title)) 36 | }; 37 | 38 | let on_delete_task = { 39 | let task_controller = task_controller.clone(); 40 | 41 | Callback::from(move |id: String| task_controller.delete_task(id)) 42 | }; 43 | 44 | let on_toggle_task = { 45 | let task_controller = task_controller.clone(); 46 | 47 | Callback::from(move |id: String| task_controller.toggle_task(id)) 48 | }; 49 | 50 | let on_close = Callback::from(|e: KeyboardEvent| onclose(e)); 51 | 52 | html! { 53 |
    54 |
    55 |

    {"Whattodo!"}

    56 | 57 | Todo App logo 58 | 59 | 60 |
    61 | 62 | 63 |
    64 |

    {"Todo"}

    65 | 66 |
    67 | 68 | 69 |
    70 | 71 | 80 |
    81 | } 82 | } 83 | 84 | /* 85 | * ARRANCAR UN CONTENEDOR DOCKER DE SURREALDB CON UN FICHERO docker-compose.yml: 86 | * sudo docker compose up -d 87 | * 88 | * ENTRAR EN LA CLI DE SURREALDB EN EL CONTENEDOR CREADO: 89 | * sudo docker exec -it surrealdb /surreal sql -c http://localhost:8000 -u root -p root --ns namespace --db database --pretty 90 | * 91 | * LISTAR LA TABLE EN LA CLI DE SURREALDB: 92 | * SELECT * FROM task ORDER BY created_at DESC; 93 | * 94 | * VER SI EL CONTENEDOR DOCKER ESTÁ INICIADO: 95 | * sudo docker ps (CON EL FLAG --a SE LISTAN TODOS LOS CONTENEDORES, ACTIVOS Y NO ACTIVOS) 96 | * 97 | * DETENER EL CONTENEDOR DE DOCKER: 98 | * sudo docker stop surrealdb 99 | * 100 | * VOLVER A INICIAR EL CONTENEDOR DE DOCKER: 101 | * sudo docker start surrealdb 102 | */ 103 | 104 | /* 105 | * DEVTOOLS EN MODO RELEASE/BUILD EN TAURI. VER: 106 | * https://github.com/tauri-apps/tauri/discussions/3059 107 | */ 108 | 109 | /* 110 | * https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html 111 | * https://freeiconshop.com/ 112 | * https://tailwindcss.com/docs/accent-color 113 | * https://docs.rs/yew/0.20.0/yew/functional/fn.use_reducer.html 114 | * https://flowbite.com/docs/forms/checkbox/#bordered 115 | */ 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Example of using a full stack with Rust. 2 | 3 | ### This repository is an example of a complete stack built entirely in Rust ("RASTY"): 4 | 5 | - [Rust](https://en.wikipedia.org/wiki/Rust_(programming_language)) as almost unique base language (except for minimal JS needed to style the interface with TailwindCSS) 6 | - [Actix-web](https://actix.rs/), a Rust framework, for the backend (our API server) 7 | - [SurrealDB](https://surrealdb.com/), the database that connects with our API, which has been developed by its creators with Rust 8 | - [Tauri App](https://tauri.app/), a Rust framework for building desktop applications, using web technology for the user interface 9 | - [Yew.rs](https://yew.rs/), Rust's web framework for building web applications with Webassembly 10 | 11 | ### In itself, the frontend applications perform a CRUD to the database using the RESTful API. 12 | 13 | --- 14 | 15 | ## To run the application stack 16 | 17 | ### 1.- actix-surrealdb-api, server/API built using Rust's Actix-web framework and SurrealDB database running in a Docker container. 18 | 19 | In addition to the obvious prerequisite of having Rust and Docker installed, we need to do the following: 20 | 21 | Create the container with a SurrealDB image and a Docker managed storage volume running at the project root: 22 | 23 | ``` 24 | $ docker compose up -d 25 | ``` 26 | 27 | If we have _cargo-watch_ installed using: 28 | 29 | ``` 30 | $ cargo install cargo-watch 31 | ``` 32 | 33 | we won't have to restart the server every time we make a code change; running the following command in the root of the project actix-surrealdb-api: 34 | 35 | ``` 36 | $ cargo watch -x run 37 | ``` 38 | 39 | rather: 40 | 41 | ``` 42 | $ cargo run 43 | ``` 44 | 45 | the server will restart automatically 😀. 46 | 47 | To stop the Docker container in which SurrealDB is running: 48 | 49 | ``` 50 | $ docker stop surrealdb 51 | ``` 52 | 53 | And to raise the container again: 54 | 55 | ``` 56 | $ docker start surrealdb 57 | ``` 58 | 59 | We can read the content of the database with the commands: 60 | 61 | ``` 62 | $ docker exec -it surrealdb /surreal sql -c http://localhost:8000 -u root -p root --ns namespace --db database --pretty 63 | 64 | namespace/database> SELECT * FROM task ORDER BY created_at DESC; 65 | ``` 66 | 67 | ### 2.- todo-yew-web, Web application developed with Rust/WebAssembly + Yew + Tailwindcss. 68 | 69 | To run the Web App, add the WebAssembly target: 70 | 71 | ``` 72 | $ rustup target add wasm32-unknown-unknown 73 | ``` 74 | 75 | Install [Trunk](https://trunkrs.dev/) (web application bundler for Rust) to run the app: 76 | 77 | ``` 78 | $ cargo install trunk 79 | ``` 80 | 81 | Run the following command in the root of the project todo-yew-web: 82 | 83 | ``` 84 | $ trunk serve 85 | ``` 86 | 87 | Build the application by running: 88 | 89 | ``` 90 | $ trunk build --release 91 | ``` 92 | 93 | ### 3.- todo-tauri-desktop, Desktop application developed with Rust/WebAssembly + Yew + Tailwindcss. 94 | 95 | Screenshot: 96 | 97 | 98 | 99 | As prerequisites, in addition to the Rust language and some OS-dependent libraries required for Tauri, you must also install the build target for browser-based WebAssembly called "wasm32-unknown-unknown" and the "Trunk" tool to the deployment and packaging of the Yew frontend (seen in the previous section). 100 | 101 | On the other hand, if we want to start from scratch, to create the scaffolding of the Tauri + Yew application it is necessary to install the Tauri app creation tool for the Cargo package manager and the Tauri CLI: 102 | 103 | ``` 104 | $ cargo install create-tauri-app && cargo install tauri-cli 105 | ``` 106 | 107 | Finally, since we use the Tailwind CSS framework, we will have to run in the root of the project todo-tauri-desktop (you need to have NodeJs installed): 108 | 109 | ``` 110 | $ npm i 111 | ``` 112 | 113 | With all this accomplished, run the app under development with the command: 114 | 115 | ``` 116 | $ cargo tauri dev 117 | ``` 118 | 119 | or build it with the command: 120 | 121 | ``` 122 | $ cargo tauri build 123 | ``` 124 | 125 | (for more information see the documentation of [Tauri](https://tauri.app/) and [Yew](https://yew.rs/).) 126 | 127 | --- 128 | 129 | ## Bonus: Frontend of the application developed with [SolidJS](https://www.solidjs.com/) (Web & Desktop). 130 | 131 | ### In the solidjs branch of the repository, the version of the stack that SolidJS uses in both the Web app frontend and the Desktop app frontend is available. Both use pnpm as bundler and dependency manager. 132 | 133 | To add the dependencies run on todo-solidjs-web: 134 | 135 | ``` 136 | $ pnpm i 137 | ``` 138 | 139 | To run it in development mode: 140 | 141 | ``` 142 | $ pnpm run dev 143 | ``` 144 | 145 | To run it in development mode: 146 | 147 | ``` 148 | $ pnpm run build 149 | ``` 150 | 151 | In the case of the desktop application developed with Tauri + SolidJS, we run the same command to add the dependencies (pnpm i). To launch the application in development mode we will execute: 152 | 153 | ``` 154 | $ pnpm tauri dev 155 | ``` 156 | 157 | And finally, to create the executable binary on our platform, we run: 158 | 159 | ``` 160 | $ pnpm tauri build 161 | ``` 162 | 163 | [comment]: # "https://user-images.githubusercontent.com/68773736/232398437-827f6fb9-2b70-4f04-ad6f-d470c868bfb6.png" 164 | -------------------------------------------------------------------------------- /todo-yew-web/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "android_system_properties" 7 | version = "0.1.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 10 | dependencies = [ 11 | "libc", 12 | ] 13 | 14 | [[package]] 15 | name = "anymap2" 16 | version = "0.13.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bincode" 28 | version = "1.3.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 31 | dependencies = [ 32 | "serde", 33 | ] 34 | 35 | [[package]] 36 | name = "boolinator" 37 | version = "2.4.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" 40 | 41 | [[package]] 42 | name = "bumpalo" 43 | version = "3.12.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" 46 | 47 | [[package]] 48 | name = "cc" 49 | version = "1.0.79" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 52 | 53 | [[package]] 54 | name = "cfg-if" 55 | version = "1.0.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 58 | 59 | [[package]] 60 | name = "chrono" 61 | version = "0.4.24" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" 64 | dependencies = [ 65 | "iana-time-zone", 66 | "js-sys", 67 | "num-integer", 68 | "num-traits", 69 | "serde", 70 | "time", 71 | "wasm-bindgen", 72 | "winapi", 73 | ] 74 | 75 | [[package]] 76 | name = "codespan-reporting" 77 | version = "0.11.1" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 80 | dependencies = [ 81 | "termcolor", 82 | "unicode-width", 83 | ] 84 | 85 | [[package]] 86 | name = "console_error_panic_hook" 87 | version = "0.1.7" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 90 | dependencies = [ 91 | "cfg-if", 92 | "wasm-bindgen", 93 | ] 94 | 95 | [[package]] 96 | name = "core-foundation-sys" 97 | version = "0.8.4" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 100 | 101 | [[package]] 102 | name = "cxx" 103 | version = "1.0.94" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" 106 | dependencies = [ 107 | "cc", 108 | "cxxbridge-flags", 109 | "cxxbridge-macro", 110 | "link-cplusplus", 111 | ] 112 | 113 | [[package]] 114 | name = "cxx-build" 115 | version = "1.0.94" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" 118 | dependencies = [ 119 | "cc", 120 | "codespan-reporting", 121 | "once_cell", 122 | "proc-macro2", 123 | "quote", 124 | "scratch", 125 | "syn 2.0.13", 126 | ] 127 | 128 | [[package]] 129 | name = "cxxbridge-flags" 130 | version = "1.0.94" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" 133 | 134 | [[package]] 135 | name = "cxxbridge-macro" 136 | version = "1.0.94" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" 139 | dependencies = [ 140 | "proc-macro2", 141 | "quote", 142 | "syn 2.0.13", 143 | ] 144 | 145 | [[package]] 146 | name = "form_urlencoded" 147 | version = "1.1.0" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 150 | dependencies = [ 151 | "percent-encoding", 152 | ] 153 | 154 | [[package]] 155 | name = "futures" 156 | version = "0.3.28" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 159 | dependencies = [ 160 | "futures-channel", 161 | "futures-core", 162 | "futures-io", 163 | "futures-sink", 164 | "futures-task", 165 | "futures-util", 166 | ] 167 | 168 | [[package]] 169 | name = "futures-channel" 170 | version = "0.3.28" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 173 | dependencies = [ 174 | "futures-core", 175 | "futures-sink", 176 | ] 177 | 178 | [[package]] 179 | name = "futures-core" 180 | version = "0.3.28" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 183 | 184 | [[package]] 185 | name = "futures-io" 186 | version = "0.3.28" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 189 | 190 | [[package]] 191 | name = "futures-macro" 192 | version = "0.3.28" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 195 | dependencies = [ 196 | "proc-macro2", 197 | "quote", 198 | "syn 2.0.13", 199 | ] 200 | 201 | [[package]] 202 | name = "futures-sink" 203 | version = "0.3.28" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 206 | 207 | [[package]] 208 | name = "futures-task" 209 | version = "0.3.28" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 212 | 213 | [[package]] 214 | name = "futures-util" 215 | version = "0.3.28" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 218 | dependencies = [ 219 | "futures-channel", 220 | "futures-core", 221 | "futures-io", 222 | "futures-macro", 223 | "futures-sink", 224 | "futures-task", 225 | "memchr", 226 | "pin-project-lite", 227 | "pin-utils", 228 | "slab", 229 | ] 230 | 231 | [[package]] 232 | name = "gloo" 233 | version = "0.8.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "3a4bef6b277b3ab073253d4bca60761240cf8d6998f4bd142211957b69a61b20" 236 | dependencies = [ 237 | "gloo-console", 238 | "gloo-dialogs", 239 | "gloo-events", 240 | "gloo-file", 241 | "gloo-history", 242 | "gloo-net 0.2.6", 243 | "gloo-render", 244 | "gloo-storage", 245 | "gloo-timers", 246 | "gloo-utils", 247 | "gloo-worker", 248 | ] 249 | 250 | [[package]] 251 | name = "gloo-console" 252 | version = "0.2.3" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" 255 | dependencies = [ 256 | "gloo-utils", 257 | "js-sys", 258 | "serde", 259 | "wasm-bindgen", 260 | "web-sys", 261 | ] 262 | 263 | [[package]] 264 | name = "gloo-dialogs" 265 | version = "0.1.1" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" 268 | dependencies = [ 269 | "wasm-bindgen", 270 | "web-sys", 271 | ] 272 | 273 | [[package]] 274 | name = "gloo-events" 275 | version = "0.1.2" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" 278 | dependencies = [ 279 | "wasm-bindgen", 280 | "web-sys", 281 | ] 282 | 283 | [[package]] 284 | name = "gloo-file" 285 | version = "0.2.3" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" 288 | dependencies = [ 289 | "gloo-events", 290 | "js-sys", 291 | "wasm-bindgen", 292 | "web-sys", 293 | ] 294 | 295 | [[package]] 296 | name = "gloo-history" 297 | version = "0.1.3" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "dd451019e0b7a2b8a7a7b23e74916601abf1135c54664e57ff71dcc26dfcdeb7" 300 | dependencies = [ 301 | "gloo-events", 302 | "gloo-utils", 303 | "serde", 304 | "serde-wasm-bindgen", 305 | "serde_urlencoded", 306 | "thiserror", 307 | "wasm-bindgen", 308 | "web-sys", 309 | ] 310 | 311 | [[package]] 312 | name = "gloo-net" 313 | version = "0.1.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "2899cb1a13be9020b010967adc6b2a8a343b6f1428b90238c9d53ca24decc6db" 316 | dependencies = [ 317 | "futures-channel", 318 | "futures-core", 319 | "futures-sink", 320 | "gloo-utils", 321 | "js-sys", 322 | "pin-project", 323 | "serde", 324 | "serde_json", 325 | "thiserror", 326 | "wasm-bindgen", 327 | "wasm-bindgen-futures", 328 | "web-sys", 329 | ] 330 | 331 | [[package]] 332 | name = "gloo-net" 333 | version = "0.2.6" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" 336 | dependencies = [ 337 | "futures-channel", 338 | "futures-core", 339 | "futures-sink", 340 | "gloo-utils", 341 | "js-sys", 342 | "pin-project", 343 | "serde", 344 | "serde_json", 345 | "thiserror", 346 | "wasm-bindgen", 347 | "wasm-bindgen-futures", 348 | "web-sys", 349 | ] 350 | 351 | [[package]] 352 | name = "gloo-render" 353 | version = "0.1.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" 356 | dependencies = [ 357 | "wasm-bindgen", 358 | "web-sys", 359 | ] 360 | 361 | [[package]] 362 | name = "gloo-storage" 363 | version = "0.2.2" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" 366 | dependencies = [ 367 | "gloo-utils", 368 | "js-sys", 369 | "serde", 370 | "serde_json", 371 | "thiserror", 372 | "wasm-bindgen", 373 | "web-sys", 374 | ] 375 | 376 | [[package]] 377 | name = "gloo-timers" 378 | version = "0.2.6" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" 381 | dependencies = [ 382 | "js-sys", 383 | "wasm-bindgen", 384 | ] 385 | 386 | [[package]] 387 | name = "gloo-utils" 388 | version = "0.1.6" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" 391 | dependencies = [ 392 | "js-sys", 393 | "serde", 394 | "serde_json", 395 | "wasm-bindgen", 396 | "web-sys", 397 | ] 398 | 399 | [[package]] 400 | name = "gloo-worker" 401 | version = "0.2.1" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" 404 | dependencies = [ 405 | "anymap2", 406 | "bincode", 407 | "gloo-console", 408 | "gloo-utils", 409 | "js-sys", 410 | "serde", 411 | "wasm-bindgen", 412 | "wasm-bindgen-futures", 413 | "web-sys", 414 | ] 415 | 416 | [[package]] 417 | name = "hashbrown" 418 | version = "0.12.3" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 421 | 422 | [[package]] 423 | name = "hermit-abi" 424 | version = "0.2.6" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 427 | dependencies = [ 428 | "libc", 429 | ] 430 | 431 | [[package]] 432 | name = "iana-time-zone" 433 | version = "0.1.56" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" 436 | dependencies = [ 437 | "android_system_properties", 438 | "core-foundation-sys", 439 | "iana-time-zone-haiku", 440 | "js-sys", 441 | "wasm-bindgen", 442 | "windows", 443 | ] 444 | 445 | [[package]] 446 | name = "iana-time-zone-haiku" 447 | version = "0.1.1" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" 450 | dependencies = [ 451 | "cxx", 452 | "cxx-build", 453 | ] 454 | 455 | [[package]] 456 | name = "implicit-clone" 457 | version = "0.3.5" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "40fc102e70475c320b185cd18c1e48bba2d7210b63970a4d581ef903e4368ef7" 460 | dependencies = [ 461 | "indexmap", 462 | ] 463 | 464 | [[package]] 465 | name = "indexmap" 466 | version = "1.9.3" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 469 | dependencies = [ 470 | "autocfg", 471 | "hashbrown", 472 | ] 473 | 474 | [[package]] 475 | name = "itoa" 476 | version = "1.0.6" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 479 | 480 | [[package]] 481 | name = "js-sys" 482 | version = "0.3.61" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" 485 | dependencies = [ 486 | "wasm-bindgen", 487 | ] 488 | 489 | [[package]] 490 | name = "libc" 491 | version = "0.2.141" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" 494 | 495 | [[package]] 496 | name = "link-cplusplus" 497 | version = "1.0.8" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 500 | dependencies = [ 501 | "cc", 502 | ] 503 | 504 | [[package]] 505 | name = "log" 506 | version = "0.4.17" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 509 | dependencies = [ 510 | "cfg-if", 511 | ] 512 | 513 | [[package]] 514 | name = "memchr" 515 | version = "2.5.0" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 518 | 519 | [[package]] 520 | name = "num-integer" 521 | version = "0.1.45" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 524 | dependencies = [ 525 | "autocfg", 526 | "num-traits", 527 | ] 528 | 529 | [[package]] 530 | name = "num-traits" 531 | version = "0.2.15" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 534 | dependencies = [ 535 | "autocfg", 536 | ] 537 | 538 | [[package]] 539 | name = "num_cpus" 540 | version = "1.15.0" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 543 | dependencies = [ 544 | "hermit-abi", 545 | "libc", 546 | ] 547 | 548 | [[package]] 549 | name = "once_cell" 550 | version = "1.17.1" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 553 | 554 | [[package]] 555 | name = "percent-encoding" 556 | version = "2.2.0" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 559 | 560 | [[package]] 561 | name = "pin-project" 562 | version = "1.0.12" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 565 | dependencies = [ 566 | "pin-project-internal", 567 | ] 568 | 569 | [[package]] 570 | name = "pin-project-internal" 571 | version = "1.0.12" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 574 | dependencies = [ 575 | "proc-macro2", 576 | "quote", 577 | "syn 1.0.109", 578 | ] 579 | 580 | [[package]] 581 | name = "pin-project-lite" 582 | version = "0.2.9" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 585 | 586 | [[package]] 587 | name = "pin-utils" 588 | version = "0.1.0" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 591 | 592 | [[package]] 593 | name = "pinned" 594 | version = "0.1.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" 597 | dependencies = [ 598 | "futures", 599 | "rustversion", 600 | "thiserror", 601 | ] 602 | 603 | [[package]] 604 | name = "prettyplease" 605 | version = "0.1.25" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" 608 | dependencies = [ 609 | "proc-macro2", 610 | "syn 1.0.109", 611 | ] 612 | 613 | [[package]] 614 | name = "proc-macro-error" 615 | version = "1.0.4" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 618 | dependencies = [ 619 | "proc-macro-error-attr", 620 | "proc-macro2", 621 | "quote", 622 | "syn 1.0.109", 623 | "version_check", 624 | ] 625 | 626 | [[package]] 627 | name = "proc-macro-error-attr" 628 | version = "1.0.4" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 631 | dependencies = [ 632 | "proc-macro2", 633 | "quote", 634 | "version_check", 635 | ] 636 | 637 | [[package]] 638 | name = "proc-macro2" 639 | version = "1.0.56" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" 642 | dependencies = [ 643 | "unicode-ident", 644 | ] 645 | 646 | [[package]] 647 | name = "prokio" 648 | version = "0.1.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "03b55e106e5791fa5a13abd13c85d6127312e8e09098059ca2bc9b03ca4cf488" 651 | dependencies = [ 652 | "futures", 653 | "gloo", 654 | "num_cpus", 655 | "once_cell", 656 | "pin-project", 657 | "pinned", 658 | "tokio", 659 | "tokio-stream", 660 | "wasm-bindgen-futures", 661 | ] 662 | 663 | [[package]] 664 | name = "quote" 665 | version = "1.0.26" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 668 | dependencies = [ 669 | "proc-macro2", 670 | ] 671 | 672 | [[package]] 673 | name = "reqwasm" 674 | version = "0.5.0" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "05b89870d729c501fa7a68c43bf4d938bbb3a8c156d333d90faa0e8b3e3212fb" 677 | dependencies = [ 678 | "gloo-net 0.1.0", 679 | ] 680 | 681 | [[package]] 682 | name = "rustversion" 683 | version = "1.0.12" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" 686 | 687 | [[package]] 688 | name = "ryu" 689 | version = "1.0.13" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 692 | 693 | [[package]] 694 | name = "scratch" 695 | version = "1.0.5" 696 | source = "registry+https://github.com/rust-lang/crates.io-index" 697 | checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" 698 | 699 | [[package]] 700 | name = "serde" 701 | version = "1.0.159" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" 704 | dependencies = [ 705 | "serde_derive", 706 | ] 707 | 708 | [[package]] 709 | name = "serde-wasm-bindgen" 710 | version = "0.4.5" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" 713 | dependencies = [ 714 | "js-sys", 715 | "serde", 716 | "wasm-bindgen", 717 | ] 718 | 719 | [[package]] 720 | name = "serde_derive" 721 | version = "1.0.159" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" 724 | dependencies = [ 725 | "proc-macro2", 726 | "quote", 727 | "syn 2.0.13", 728 | ] 729 | 730 | [[package]] 731 | name = "serde_json" 732 | version = "1.0.95" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" 735 | dependencies = [ 736 | "itoa", 737 | "ryu", 738 | "serde", 739 | ] 740 | 741 | [[package]] 742 | name = "serde_urlencoded" 743 | version = "0.7.1" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 746 | dependencies = [ 747 | "form_urlencoded", 748 | "itoa", 749 | "ryu", 750 | "serde", 751 | ] 752 | 753 | [[package]] 754 | name = "slab" 755 | version = "0.4.8" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 758 | dependencies = [ 759 | "autocfg", 760 | ] 761 | 762 | [[package]] 763 | name = "syn" 764 | version = "1.0.109" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 767 | dependencies = [ 768 | "proc-macro2", 769 | "quote", 770 | "unicode-ident", 771 | ] 772 | 773 | [[package]] 774 | name = "syn" 775 | version = "2.0.13" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" 778 | dependencies = [ 779 | "proc-macro2", 780 | "quote", 781 | "unicode-ident", 782 | ] 783 | 784 | [[package]] 785 | name = "termcolor" 786 | version = "1.2.0" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" 789 | dependencies = [ 790 | "winapi-util", 791 | ] 792 | 793 | [[package]] 794 | name = "thiserror" 795 | version = "1.0.40" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 798 | dependencies = [ 799 | "thiserror-impl", 800 | ] 801 | 802 | [[package]] 803 | name = "thiserror-impl" 804 | version = "1.0.40" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 807 | dependencies = [ 808 | "proc-macro2", 809 | "quote", 810 | "syn 2.0.13", 811 | ] 812 | 813 | [[package]] 814 | name = "time" 815 | version = "0.1.45" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 818 | dependencies = [ 819 | "libc", 820 | "wasi", 821 | "winapi", 822 | ] 823 | 824 | [[package]] 825 | name = "todo_yew_web" 826 | version = "0.1.0" 827 | dependencies = [ 828 | "chrono", 829 | "gloo-dialogs", 830 | "reqwasm", 831 | "serde", 832 | "wasm-bindgen-futures", 833 | "web-sys", 834 | "yew", 835 | ] 836 | 837 | [[package]] 838 | name = "tokio" 839 | version = "1.27.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" 842 | dependencies = [ 843 | "autocfg", 844 | "pin-project-lite", 845 | "windows-sys", 846 | ] 847 | 848 | [[package]] 849 | name = "tokio-stream" 850 | version = "0.1.12" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" 853 | dependencies = [ 854 | "futures-core", 855 | "pin-project-lite", 856 | "tokio", 857 | ] 858 | 859 | [[package]] 860 | name = "tracing" 861 | version = "0.1.37" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 864 | dependencies = [ 865 | "cfg-if", 866 | "pin-project-lite", 867 | "tracing-attributes", 868 | "tracing-core", 869 | ] 870 | 871 | [[package]] 872 | name = "tracing-attributes" 873 | version = "0.1.23" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 876 | dependencies = [ 877 | "proc-macro2", 878 | "quote", 879 | "syn 1.0.109", 880 | ] 881 | 882 | [[package]] 883 | name = "tracing-core" 884 | version = "0.1.30" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 887 | dependencies = [ 888 | "once_cell", 889 | ] 890 | 891 | [[package]] 892 | name = "unicode-ident" 893 | version = "1.0.8" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 896 | 897 | [[package]] 898 | name = "unicode-width" 899 | version = "0.1.10" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 902 | 903 | [[package]] 904 | name = "version_check" 905 | version = "0.9.4" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 908 | 909 | [[package]] 910 | name = "wasi" 911 | version = "0.10.0+wasi-snapshot-preview1" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 914 | 915 | [[package]] 916 | name = "wasm-bindgen" 917 | version = "0.2.84" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" 920 | dependencies = [ 921 | "cfg-if", 922 | "serde", 923 | "serde_json", 924 | "wasm-bindgen-macro", 925 | ] 926 | 927 | [[package]] 928 | name = "wasm-bindgen-backend" 929 | version = "0.2.84" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" 932 | dependencies = [ 933 | "bumpalo", 934 | "log", 935 | "once_cell", 936 | "proc-macro2", 937 | "quote", 938 | "syn 1.0.109", 939 | "wasm-bindgen-shared", 940 | ] 941 | 942 | [[package]] 943 | name = "wasm-bindgen-futures" 944 | version = "0.4.34" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" 947 | dependencies = [ 948 | "cfg-if", 949 | "js-sys", 950 | "wasm-bindgen", 951 | "web-sys", 952 | ] 953 | 954 | [[package]] 955 | name = "wasm-bindgen-macro" 956 | version = "0.2.84" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" 959 | dependencies = [ 960 | "quote", 961 | "wasm-bindgen-macro-support", 962 | ] 963 | 964 | [[package]] 965 | name = "wasm-bindgen-macro-support" 966 | version = "0.2.84" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" 969 | dependencies = [ 970 | "proc-macro2", 971 | "quote", 972 | "syn 1.0.109", 973 | "wasm-bindgen-backend", 974 | "wasm-bindgen-shared", 975 | ] 976 | 977 | [[package]] 978 | name = "wasm-bindgen-shared" 979 | version = "0.2.84" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" 982 | 983 | [[package]] 984 | name = "web-sys" 985 | version = "0.3.61" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" 988 | dependencies = [ 989 | "js-sys", 990 | "wasm-bindgen", 991 | ] 992 | 993 | [[package]] 994 | name = "winapi" 995 | version = "0.3.9" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 998 | dependencies = [ 999 | "winapi-i686-pc-windows-gnu", 1000 | "winapi-x86_64-pc-windows-gnu", 1001 | ] 1002 | 1003 | [[package]] 1004 | name = "winapi-i686-pc-windows-gnu" 1005 | version = "0.4.0" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1008 | 1009 | [[package]] 1010 | name = "winapi-util" 1011 | version = "0.1.5" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1014 | dependencies = [ 1015 | "winapi", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "winapi-x86_64-pc-windows-gnu" 1020 | version = "0.4.0" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1023 | 1024 | [[package]] 1025 | name = "windows" 1026 | version = "0.48.0" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 1029 | dependencies = [ 1030 | "windows-targets 0.48.0", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "windows-sys" 1035 | version = "0.45.0" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1038 | dependencies = [ 1039 | "windows-targets 0.42.2", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "windows-targets" 1044 | version = "0.42.2" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1047 | dependencies = [ 1048 | "windows_aarch64_gnullvm 0.42.2", 1049 | "windows_aarch64_msvc 0.42.2", 1050 | "windows_i686_gnu 0.42.2", 1051 | "windows_i686_msvc 0.42.2", 1052 | "windows_x86_64_gnu 0.42.2", 1053 | "windows_x86_64_gnullvm 0.42.2", 1054 | "windows_x86_64_msvc 0.42.2", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "windows-targets" 1059 | version = "0.48.0" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 1062 | dependencies = [ 1063 | "windows_aarch64_gnullvm 0.48.0", 1064 | "windows_aarch64_msvc 0.48.0", 1065 | "windows_i686_gnu 0.48.0", 1066 | "windows_i686_msvc 0.48.0", 1067 | "windows_x86_64_gnu 0.48.0", 1068 | "windows_x86_64_gnullvm 0.48.0", 1069 | "windows_x86_64_msvc 0.48.0", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "windows_aarch64_gnullvm" 1074 | version = "0.42.2" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1077 | 1078 | [[package]] 1079 | name = "windows_aarch64_gnullvm" 1080 | version = "0.48.0" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 1083 | 1084 | [[package]] 1085 | name = "windows_aarch64_msvc" 1086 | version = "0.42.2" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1089 | 1090 | [[package]] 1091 | name = "windows_aarch64_msvc" 1092 | version = "0.48.0" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 1095 | 1096 | [[package]] 1097 | name = "windows_i686_gnu" 1098 | version = "0.42.2" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1101 | 1102 | [[package]] 1103 | name = "windows_i686_gnu" 1104 | version = "0.48.0" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 1107 | 1108 | [[package]] 1109 | name = "windows_i686_msvc" 1110 | version = "0.42.2" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1113 | 1114 | [[package]] 1115 | name = "windows_i686_msvc" 1116 | version = "0.48.0" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 1119 | 1120 | [[package]] 1121 | name = "windows_x86_64_gnu" 1122 | version = "0.42.2" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1125 | 1126 | [[package]] 1127 | name = "windows_x86_64_gnu" 1128 | version = "0.48.0" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 1131 | 1132 | [[package]] 1133 | name = "windows_x86_64_gnullvm" 1134 | version = "0.42.2" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1137 | 1138 | [[package]] 1139 | name = "windows_x86_64_gnullvm" 1140 | version = "0.48.0" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 1143 | 1144 | [[package]] 1145 | name = "windows_x86_64_msvc" 1146 | version = "0.42.2" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1149 | 1150 | [[package]] 1151 | name = "windows_x86_64_msvc" 1152 | version = "0.48.0" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 1155 | 1156 | [[package]] 1157 | name = "yew" 1158 | version = "0.20.0" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "5dbecfe44343b70cc2932c3eb445425969ae21754a8ab3a0966981c1cf7af1cc" 1161 | dependencies = [ 1162 | "console_error_panic_hook", 1163 | "futures", 1164 | "gloo", 1165 | "implicit-clone", 1166 | "indexmap", 1167 | "js-sys", 1168 | "prokio", 1169 | "rustversion", 1170 | "serde", 1171 | "slab", 1172 | "thiserror", 1173 | "tokio", 1174 | "tracing", 1175 | "wasm-bindgen", 1176 | "wasm-bindgen-futures", 1177 | "web-sys", 1178 | "yew-macro", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "yew-macro" 1183 | version = "0.20.0" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "b64c253c1d401f1ea868ca9988db63958cfa15a69f739101f338d6f05eea8301" 1186 | dependencies = [ 1187 | "boolinator", 1188 | "once_cell", 1189 | "prettyplease", 1190 | "proc-macro-error", 1191 | "proc-macro2", 1192 | "quote", 1193 | "syn 1.0.109", 1194 | ] 1195 | -------------------------------------------------------------------------------- /todo-yew-web/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo_yew_web", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "devDependencies": { 8 | "tailwindcss": "^3.3.1" 9 | } 10 | }, 11 | "node_modules/@nodelib/fs.scandir": { 12 | "version": "2.1.5", 13 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 14 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 15 | "dev": true, 16 | "dependencies": { 17 | "@nodelib/fs.stat": "2.0.5", 18 | "run-parallel": "^1.1.9" 19 | }, 20 | "engines": { 21 | "node": ">= 8" 22 | } 23 | }, 24 | "node_modules/@nodelib/fs.stat": { 25 | "version": "2.0.5", 26 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 27 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 28 | "dev": true, 29 | "engines": { 30 | "node": ">= 8" 31 | } 32 | }, 33 | "node_modules/@nodelib/fs.walk": { 34 | "version": "1.2.8", 35 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 36 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 37 | "dev": true, 38 | "dependencies": { 39 | "@nodelib/fs.scandir": "2.1.5", 40 | "fastq": "^1.6.0" 41 | }, 42 | "engines": { 43 | "node": ">= 8" 44 | } 45 | }, 46 | "node_modules/any-promise": { 47 | "version": "1.3.0", 48 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 49 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", 50 | "dev": true 51 | }, 52 | "node_modules/anymatch": { 53 | "version": "3.1.3", 54 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 55 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 56 | "dev": true, 57 | "dependencies": { 58 | "normalize-path": "^3.0.0", 59 | "picomatch": "^2.0.4" 60 | }, 61 | "engines": { 62 | "node": ">= 8" 63 | } 64 | }, 65 | "node_modules/arg": { 66 | "version": "5.0.2", 67 | "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", 68 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", 69 | "dev": true 70 | }, 71 | "node_modules/balanced-match": { 72 | "version": "1.0.2", 73 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 74 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 75 | "dev": true 76 | }, 77 | "node_modules/binary-extensions": { 78 | "version": "2.2.0", 79 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 80 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 81 | "dev": true, 82 | "engines": { 83 | "node": ">=8" 84 | } 85 | }, 86 | "node_modules/brace-expansion": { 87 | "version": "1.1.11", 88 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 89 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 90 | "dev": true, 91 | "dependencies": { 92 | "balanced-match": "^1.0.0", 93 | "concat-map": "0.0.1" 94 | } 95 | }, 96 | "node_modules/braces": { 97 | "version": "3.0.2", 98 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 99 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 100 | "dev": true, 101 | "dependencies": { 102 | "fill-range": "^7.0.1" 103 | }, 104 | "engines": { 105 | "node": ">=8" 106 | } 107 | }, 108 | "node_modules/camelcase-css": { 109 | "version": "2.0.1", 110 | "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", 111 | "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", 112 | "dev": true, 113 | "engines": { 114 | "node": ">= 6" 115 | } 116 | }, 117 | "node_modules/chokidar": { 118 | "version": "3.5.3", 119 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 120 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 121 | "dev": true, 122 | "funding": [ 123 | { 124 | "type": "individual", 125 | "url": "https://paulmillr.com/funding/" 126 | } 127 | ], 128 | "dependencies": { 129 | "anymatch": "~3.1.2", 130 | "braces": "~3.0.2", 131 | "glob-parent": "~5.1.2", 132 | "is-binary-path": "~2.1.0", 133 | "is-glob": "~4.0.1", 134 | "normalize-path": "~3.0.0", 135 | "readdirp": "~3.6.0" 136 | }, 137 | "engines": { 138 | "node": ">= 8.10.0" 139 | }, 140 | "optionalDependencies": { 141 | "fsevents": "~2.3.2" 142 | } 143 | }, 144 | "node_modules/chokidar/node_modules/glob-parent": { 145 | "version": "5.1.2", 146 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 147 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 148 | "dev": true, 149 | "dependencies": { 150 | "is-glob": "^4.0.1" 151 | }, 152 | "engines": { 153 | "node": ">= 6" 154 | } 155 | }, 156 | "node_modules/color-name": { 157 | "version": "1.1.4", 158 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 159 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 160 | "dev": true 161 | }, 162 | "node_modules/commander": { 163 | "version": "4.1.1", 164 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 165 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 166 | "dev": true, 167 | "engines": { 168 | "node": ">= 6" 169 | } 170 | }, 171 | "node_modules/concat-map": { 172 | "version": "0.0.1", 173 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 174 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 175 | "dev": true 176 | }, 177 | "node_modules/cssesc": { 178 | "version": "3.0.0", 179 | "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", 180 | "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", 181 | "dev": true, 182 | "bin": { 183 | "cssesc": "bin/cssesc" 184 | }, 185 | "engines": { 186 | "node": ">=4" 187 | } 188 | }, 189 | "node_modules/didyoumean": { 190 | "version": "1.2.2", 191 | "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", 192 | "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", 193 | "dev": true 194 | }, 195 | "node_modules/dlv": { 196 | "version": "1.1.3", 197 | "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", 198 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", 199 | "dev": true 200 | }, 201 | "node_modules/fast-glob": { 202 | "version": "3.2.12", 203 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", 204 | "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", 205 | "dev": true, 206 | "dependencies": { 207 | "@nodelib/fs.stat": "^2.0.2", 208 | "@nodelib/fs.walk": "^1.2.3", 209 | "glob-parent": "^5.1.2", 210 | "merge2": "^1.3.0", 211 | "micromatch": "^4.0.4" 212 | }, 213 | "engines": { 214 | "node": ">=8.6.0" 215 | } 216 | }, 217 | "node_modules/fast-glob/node_modules/glob-parent": { 218 | "version": "5.1.2", 219 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 220 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 221 | "dev": true, 222 | "dependencies": { 223 | "is-glob": "^4.0.1" 224 | }, 225 | "engines": { 226 | "node": ">= 6" 227 | } 228 | }, 229 | "node_modules/fastq": { 230 | "version": "1.15.0", 231 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 232 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 233 | "dev": true, 234 | "dependencies": { 235 | "reusify": "^1.0.4" 236 | } 237 | }, 238 | "node_modules/fill-range": { 239 | "version": "7.0.1", 240 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 241 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 242 | "dev": true, 243 | "dependencies": { 244 | "to-regex-range": "^5.0.1" 245 | }, 246 | "engines": { 247 | "node": ">=8" 248 | } 249 | }, 250 | "node_modules/fs.realpath": { 251 | "version": "1.0.0", 252 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 253 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 254 | "dev": true 255 | }, 256 | "node_modules/fsevents": { 257 | "version": "2.3.2", 258 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 259 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 260 | "dev": true, 261 | "hasInstallScript": true, 262 | "optional": true, 263 | "os": [ 264 | "darwin" 265 | ], 266 | "engines": { 267 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 268 | } 269 | }, 270 | "node_modules/function-bind": { 271 | "version": "1.1.1", 272 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 273 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 274 | "dev": true 275 | }, 276 | "node_modules/glob": { 277 | "version": "7.1.6", 278 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 279 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 280 | "dev": true, 281 | "dependencies": { 282 | "fs.realpath": "^1.0.0", 283 | "inflight": "^1.0.4", 284 | "inherits": "2", 285 | "minimatch": "^3.0.4", 286 | "once": "^1.3.0", 287 | "path-is-absolute": "^1.0.0" 288 | }, 289 | "engines": { 290 | "node": "*" 291 | }, 292 | "funding": { 293 | "url": "https://github.com/sponsors/isaacs" 294 | } 295 | }, 296 | "node_modules/glob-parent": { 297 | "version": "6.0.2", 298 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 299 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 300 | "dev": true, 301 | "dependencies": { 302 | "is-glob": "^4.0.3" 303 | }, 304 | "engines": { 305 | "node": ">=10.13.0" 306 | } 307 | }, 308 | "node_modules/has": { 309 | "version": "1.0.3", 310 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 311 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 312 | "dev": true, 313 | "dependencies": { 314 | "function-bind": "^1.1.1" 315 | }, 316 | "engines": { 317 | "node": ">= 0.4.0" 318 | } 319 | }, 320 | "node_modules/inflight": { 321 | "version": "1.0.6", 322 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 323 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 324 | "dev": true, 325 | "dependencies": { 326 | "once": "^1.3.0", 327 | "wrappy": "1" 328 | } 329 | }, 330 | "node_modules/inherits": { 331 | "version": "2.0.4", 332 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 333 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 334 | "dev": true 335 | }, 336 | "node_modules/is-binary-path": { 337 | "version": "2.1.0", 338 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 339 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 340 | "dev": true, 341 | "dependencies": { 342 | "binary-extensions": "^2.0.0" 343 | }, 344 | "engines": { 345 | "node": ">=8" 346 | } 347 | }, 348 | "node_modules/is-core-module": { 349 | "version": "2.11.0", 350 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", 351 | "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", 352 | "dev": true, 353 | "dependencies": { 354 | "has": "^1.0.3" 355 | }, 356 | "funding": { 357 | "url": "https://github.com/sponsors/ljharb" 358 | } 359 | }, 360 | "node_modules/is-extglob": { 361 | "version": "2.1.1", 362 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 363 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 364 | "dev": true, 365 | "engines": { 366 | "node": ">=0.10.0" 367 | } 368 | }, 369 | "node_modules/is-glob": { 370 | "version": "4.0.3", 371 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 372 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 373 | "dev": true, 374 | "dependencies": { 375 | "is-extglob": "^2.1.1" 376 | }, 377 | "engines": { 378 | "node": ">=0.10.0" 379 | } 380 | }, 381 | "node_modules/is-number": { 382 | "version": "7.0.0", 383 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 384 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 385 | "dev": true, 386 | "engines": { 387 | "node": ">=0.12.0" 388 | } 389 | }, 390 | "node_modules/jiti": { 391 | "version": "1.18.2", 392 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", 393 | "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", 394 | "dev": true, 395 | "bin": { 396 | "jiti": "bin/jiti.js" 397 | } 398 | }, 399 | "node_modules/lilconfig": { 400 | "version": "2.1.0", 401 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", 402 | "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", 403 | "dev": true, 404 | "engines": { 405 | "node": ">=10" 406 | } 407 | }, 408 | "node_modules/lines-and-columns": { 409 | "version": "1.2.4", 410 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 411 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 412 | "dev": true 413 | }, 414 | "node_modules/merge2": { 415 | "version": "1.4.1", 416 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 417 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 418 | "dev": true, 419 | "engines": { 420 | "node": ">= 8" 421 | } 422 | }, 423 | "node_modules/micromatch": { 424 | "version": "4.0.5", 425 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 426 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 427 | "dev": true, 428 | "dependencies": { 429 | "braces": "^3.0.2", 430 | "picomatch": "^2.3.1" 431 | }, 432 | "engines": { 433 | "node": ">=8.6" 434 | } 435 | }, 436 | "node_modules/minimatch": { 437 | "version": "3.1.2", 438 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 439 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 440 | "dev": true, 441 | "dependencies": { 442 | "brace-expansion": "^1.1.7" 443 | }, 444 | "engines": { 445 | "node": "*" 446 | } 447 | }, 448 | "node_modules/mz": { 449 | "version": "2.7.0", 450 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", 451 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", 452 | "dev": true, 453 | "dependencies": { 454 | "any-promise": "^1.0.0", 455 | "object-assign": "^4.0.1", 456 | "thenify-all": "^1.0.0" 457 | } 458 | }, 459 | "node_modules/nanoid": { 460 | "version": "3.3.6", 461 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 462 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 463 | "dev": true, 464 | "funding": [ 465 | { 466 | "type": "github", 467 | "url": "https://github.com/sponsors/ai" 468 | } 469 | ], 470 | "bin": { 471 | "nanoid": "bin/nanoid.cjs" 472 | }, 473 | "engines": { 474 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 475 | } 476 | }, 477 | "node_modules/normalize-path": { 478 | "version": "3.0.0", 479 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 480 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 481 | "dev": true, 482 | "engines": { 483 | "node": ">=0.10.0" 484 | } 485 | }, 486 | "node_modules/object-assign": { 487 | "version": "4.1.1", 488 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 489 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 490 | "dev": true, 491 | "engines": { 492 | "node": ">=0.10.0" 493 | } 494 | }, 495 | "node_modules/object-hash": { 496 | "version": "3.0.0", 497 | "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", 498 | "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", 499 | "dev": true, 500 | "engines": { 501 | "node": ">= 6" 502 | } 503 | }, 504 | "node_modules/once": { 505 | "version": "1.4.0", 506 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 507 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 508 | "dev": true, 509 | "dependencies": { 510 | "wrappy": "1" 511 | } 512 | }, 513 | "node_modules/path-is-absolute": { 514 | "version": "1.0.1", 515 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 516 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 517 | "dev": true, 518 | "engines": { 519 | "node": ">=0.10.0" 520 | } 521 | }, 522 | "node_modules/path-parse": { 523 | "version": "1.0.7", 524 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 525 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 526 | "dev": true 527 | }, 528 | "node_modules/picocolors": { 529 | "version": "1.0.0", 530 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 531 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 532 | "dev": true 533 | }, 534 | "node_modules/picomatch": { 535 | "version": "2.3.1", 536 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 537 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 538 | "dev": true, 539 | "engines": { 540 | "node": ">=8.6" 541 | }, 542 | "funding": { 543 | "url": "https://github.com/sponsors/jonschlinkert" 544 | } 545 | }, 546 | "node_modules/pify": { 547 | "version": "2.3.0", 548 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 549 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 550 | "dev": true, 551 | "engines": { 552 | "node": ">=0.10.0" 553 | } 554 | }, 555 | "node_modules/pirates": { 556 | "version": "4.0.5", 557 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", 558 | "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", 559 | "dev": true, 560 | "engines": { 561 | "node": ">= 6" 562 | } 563 | }, 564 | "node_modules/postcss": { 565 | "version": "8.4.21", 566 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", 567 | "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", 568 | "dev": true, 569 | "funding": [ 570 | { 571 | "type": "opencollective", 572 | "url": "https://opencollective.com/postcss/" 573 | }, 574 | { 575 | "type": "tidelift", 576 | "url": "https://tidelift.com/funding/github/npm/postcss" 577 | } 578 | ], 579 | "dependencies": { 580 | "nanoid": "^3.3.4", 581 | "picocolors": "^1.0.0", 582 | "source-map-js": "^1.0.2" 583 | }, 584 | "engines": { 585 | "node": "^10 || ^12 || >=14" 586 | } 587 | }, 588 | "node_modules/postcss-import": { 589 | "version": "14.1.0", 590 | "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", 591 | "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", 592 | "dev": true, 593 | "dependencies": { 594 | "postcss-value-parser": "^4.0.0", 595 | "read-cache": "^1.0.0", 596 | "resolve": "^1.1.7" 597 | }, 598 | "engines": { 599 | "node": ">=10.0.0" 600 | }, 601 | "peerDependencies": { 602 | "postcss": "^8.0.0" 603 | } 604 | }, 605 | "node_modules/postcss-js": { 606 | "version": "4.0.1", 607 | "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", 608 | "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", 609 | "dev": true, 610 | "dependencies": { 611 | "camelcase-css": "^2.0.1" 612 | }, 613 | "engines": { 614 | "node": "^12 || ^14 || >= 16" 615 | }, 616 | "funding": { 617 | "type": "opencollective", 618 | "url": "https://opencollective.com/postcss/" 619 | }, 620 | "peerDependencies": { 621 | "postcss": "^8.4.21" 622 | } 623 | }, 624 | "node_modules/postcss-load-config": { 625 | "version": "3.1.4", 626 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", 627 | "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", 628 | "dev": true, 629 | "dependencies": { 630 | "lilconfig": "^2.0.5", 631 | "yaml": "^1.10.2" 632 | }, 633 | "engines": { 634 | "node": ">= 10" 635 | }, 636 | "funding": { 637 | "type": "opencollective", 638 | "url": "https://opencollective.com/postcss/" 639 | }, 640 | "peerDependencies": { 641 | "postcss": ">=8.0.9", 642 | "ts-node": ">=9.0.0" 643 | }, 644 | "peerDependenciesMeta": { 645 | "postcss": { 646 | "optional": true 647 | }, 648 | "ts-node": { 649 | "optional": true 650 | } 651 | } 652 | }, 653 | "node_modules/postcss-nested": { 654 | "version": "6.0.0", 655 | "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", 656 | "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", 657 | "dev": true, 658 | "dependencies": { 659 | "postcss-selector-parser": "^6.0.10" 660 | }, 661 | "engines": { 662 | "node": ">=12.0" 663 | }, 664 | "funding": { 665 | "type": "opencollective", 666 | "url": "https://opencollective.com/postcss/" 667 | }, 668 | "peerDependencies": { 669 | "postcss": "^8.2.14" 670 | } 671 | }, 672 | "node_modules/postcss-selector-parser": { 673 | "version": "6.0.11", 674 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", 675 | "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", 676 | "dev": true, 677 | "dependencies": { 678 | "cssesc": "^3.0.0", 679 | "util-deprecate": "^1.0.2" 680 | }, 681 | "engines": { 682 | "node": ">=4" 683 | } 684 | }, 685 | "node_modules/postcss-value-parser": { 686 | "version": "4.2.0", 687 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", 688 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", 689 | "dev": true 690 | }, 691 | "node_modules/queue-microtask": { 692 | "version": "1.2.3", 693 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 694 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 695 | "dev": true, 696 | "funding": [ 697 | { 698 | "type": "github", 699 | "url": "https://github.com/sponsors/feross" 700 | }, 701 | { 702 | "type": "patreon", 703 | "url": "https://www.patreon.com/feross" 704 | }, 705 | { 706 | "type": "consulting", 707 | "url": "https://feross.org/support" 708 | } 709 | ] 710 | }, 711 | "node_modules/quick-lru": { 712 | "version": "5.1.1", 713 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 714 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 715 | "dev": true, 716 | "engines": { 717 | "node": ">=10" 718 | }, 719 | "funding": { 720 | "url": "https://github.com/sponsors/sindresorhus" 721 | } 722 | }, 723 | "node_modules/read-cache": { 724 | "version": "1.0.0", 725 | "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", 726 | "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", 727 | "dev": true, 728 | "dependencies": { 729 | "pify": "^2.3.0" 730 | } 731 | }, 732 | "node_modules/readdirp": { 733 | "version": "3.6.0", 734 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 735 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 736 | "dev": true, 737 | "dependencies": { 738 | "picomatch": "^2.2.1" 739 | }, 740 | "engines": { 741 | "node": ">=8.10.0" 742 | } 743 | }, 744 | "node_modules/resolve": { 745 | "version": "1.22.2", 746 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", 747 | "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", 748 | "dev": true, 749 | "dependencies": { 750 | "is-core-module": "^2.11.0", 751 | "path-parse": "^1.0.7", 752 | "supports-preserve-symlinks-flag": "^1.0.0" 753 | }, 754 | "bin": { 755 | "resolve": "bin/resolve" 756 | }, 757 | "funding": { 758 | "url": "https://github.com/sponsors/ljharb" 759 | } 760 | }, 761 | "node_modules/reusify": { 762 | "version": "1.0.4", 763 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 764 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 765 | "dev": true, 766 | "engines": { 767 | "iojs": ">=1.0.0", 768 | "node": ">=0.10.0" 769 | } 770 | }, 771 | "node_modules/run-parallel": { 772 | "version": "1.2.0", 773 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 774 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 775 | "dev": true, 776 | "funding": [ 777 | { 778 | "type": "github", 779 | "url": "https://github.com/sponsors/feross" 780 | }, 781 | { 782 | "type": "patreon", 783 | "url": "https://www.patreon.com/feross" 784 | }, 785 | { 786 | "type": "consulting", 787 | "url": "https://feross.org/support" 788 | } 789 | ], 790 | "dependencies": { 791 | "queue-microtask": "^1.2.2" 792 | } 793 | }, 794 | "node_modules/source-map-js": { 795 | "version": "1.0.2", 796 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 797 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 798 | "dev": true, 799 | "engines": { 800 | "node": ">=0.10.0" 801 | } 802 | }, 803 | "node_modules/sucrase": { 804 | "version": "3.31.0", 805 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.31.0.tgz", 806 | "integrity": "sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ==", 807 | "dev": true, 808 | "dependencies": { 809 | "commander": "^4.0.0", 810 | "glob": "7.1.6", 811 | "lines-and-columns": "^1.1.6", 812 | "mz": "^2.7.0", 813 | "pirates": "^4.0.1", 814 | "ts-interface-checker": "^0.1.9" 815 | }, 816 | "bin": { 817 | "sucrase": "bin/sucrase", 818 | "sucrase-node": "bin/sucrase-node" 819 | }, 820 | "engines": { 821 | "node": ">=8" 822 | } 823 | }, 824 | "node_modules/supports-preserve-symlinks-flag": { 825 | "version": "1.0.0", 826 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 827 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 828 | "dev": true, 829 | "engines": { 830 | "node": ">= 0.4" 831 | }, 832 | "funding": { 833 | "url": "https://github.com/sponsors/ljharb" 834 | } 835 | }, 836 | "node_modules/tailwindcss": { 837 | "version": "3.3.1", 838 | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", 839 | "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", 840 | "dev": true, 841 | "dependencies": { 842 | "arg": "^5.0.2", 843 | "chokidar": "^3.5.3", 844 | "color-name": "^1.1.4", 845 | "didyoumean": "^1.2.2", 846 | "dlv": "^1.1.3", 847 | "fast-glob": "^3.2.12", 848 | "glob-parent": "^6.0.2", 849 | "is-glob": "^4.0.3", 850 | "jiti": "^1.17.2", 851 | "lilconfig": "^2.0.6", 852 | "micromatch": "^4.0.5", 853 | "normalize-path": "^3.0.0", 854 | "object-hash": "^3.0.0", 855 | "picocolors": "^1.0.0", 856 | "postcss": "^8.0.9", 857 | "postcss-import": "^14.1.0", 858 | "postcss-js": "^4.0.0", 859 | "postcss-load-config": "^3.1.4", 860 | "postcss-nested": "6.0.0", 861 | "postcss-selector-parser": "^6.0.11", 862 | "postcss-value-parser": "^4.2.0", 863 | "quick-lru": "^5.1.1", 864 | "resolve": "^1.22.1", 865 | "sucrase": "^3.29.0" 866 | }, 867 | "bin": { 868 | "tailwind": "lib/cli.js", 869 | "tailwindcss": "lib/cli.js" 870 | }, 871 | "engines": { 872 | "node": ">=12.13.0" 873 | }, 874 | "peerDependencies": { 875 | "postcss": "^8.0.9" 876 | } 877 | }, 878 | "node_modules/thenify": { 879 | "version": "3.3.1", 880 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", 881 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", 882 | "dev": true, 883 | "dependencies": { 884 | "any-promise": "^1.0.0" 885 | } 886 | }, 887 | "node_modules/thenify-all": { 888 | "version": "1.6.0", 889 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", 890 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", 891 | "dev": true, 892 | "dependencies": { 893 | "thenify": ">= 3.1.0 < 4" 894 | }, 895 | "engines": { 896 | "node": ">=0.8" 897 | } 898 | }, 899 | "node_modules/to-regex-range": { 900 | "version": "5.0.1", 901 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 902 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 903 | "dev": true, 904 | "dependencies": { 905 | "is-number": "^7.0.0" 906 | }, 907 | "engines": { 908 | "node": ">=8.0" 909 | } 910 | }, 911 | "node_modules/ts-interface-checker": { 912 | "version": "0.1.13", 913 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", 914 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", 915 | "dev": true 916 | }, 917 | "node_modules/util-deprecate": { 918 | "version": "1.0.2", 919 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 920 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 921 | "dev": true 922 | }, 923 | "node_modules/wrappy": { 924 | "version": "1.0.2", 925 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 926 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 927 | "dev": true 928 | }, 929 | "node_modules/yaml": { 930 | "version": "1.10.2", 931 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 932 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 933 | "dev": true, 934 | "engines": { 935 | "node": ">= 6" 936 | } 937 | } 938 | }, 939 | "dependencies": { 940 | "@nodelib/fs.scandir": { 941 | "version": "2.1.5", 942 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 943 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 944 | "dev": true, 945 | "requires": { 946 | "@nodelib/fs.stat": "2.0.5", 947 | "run-parallel": "^1.1.9" 948 | } 949 | }, 950 | "@nodelib/fs.stat": { 951 | "version": "2.0.5", 952 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 953 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 954 | "dev": true 955 | }, 956 | "@nodelib/fs.walk": { 957 | "version": "1.2.8", 958 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 959 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 960 | "dev": true, 961 | "requires": { 962 | "@nodelib/fs.scandir": "2.1.5", 963 | "fastq": "^1.6.0" 964 | } 965 | }, 966 | "any-promise": { 967 | "version": "1.3.0", 968 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 969 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", 970 | "dev": true 971 | }, 972 | "anymatch": { 973 | "version": "3.1.3", 974 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 975 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 976 | "dev": true, 977 | "requires": { 978 | "normalize-path": "^3.0.0", 979 | "picomatch": "^2.0.4" 980 | } 981 | }, 982 | "arg": { 983 | "version": "5.0.2", 984 | "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", 985 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", 986 | "dev": true 987 | }, 988 | "balanced-match": { 989 | "version": "1.0.2", 990 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 991 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 992 | "dev": true 993 | }, 994 | "binary-extensions": { 995 | "version": "2.2.0", 996 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 997 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 998 | "dev": true 999 | }, 1000 | "brace-expansion": { 1001 | "version": "1.1.11", 1002 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1003 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1004 | "dev": true, 1005 | "requires": { 1006 | "balanced-match": "^1.0.0", 1007 | "concat-map": "0.0.1" 1008 | } 1009 | }, 1010 | "braces": { 1011 | "version": "3.0.2", 1012 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1013 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1014 | "dev": true, 1015 | "requires": { 1016 | "fill-range": "^7.0.1" 1017 | } 1018 | }, 1019 | "camelcase-css": { 1020 | "version": "2.0.1", 1021 | "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", 1022 | "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", 1023 | "dev": true 1024 | }, 1025 | "chokidar": { 1026 | "version": "3.5.3", 1027 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 1028 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 1029 | "dev": true, 1030 | "requires": { 1031 | "anymatch": "~3.1.2", 1032 | "braces": "~3.0.2", 1033 | "fsevents": "~2.3.2", 1034 | "glob-parent": "~5.1.2", 1035 | "is-binary-path": "~2.1.0", 1036 | "is-glob": "~4.0.1", 1037 | "normalize-path": "~3.0.0", 1038 | "readdirp": "~3.6.0" 1039 | }, 1040 | "dependencies": { 1041 | "glob-parent": { 1042 | "version": "5.1.2", 1043 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1044 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1045 | "dev": true, 1046 | "requires": { 1047 | "is-glob": "^4.0.1" 1048 | } 1049 | } 1050 | } 1051 | }, 1052 | "color-name": { 1053 | "version": "1.1.4", 1054 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1055 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1056 | "dev": true 1057 | }, 1058 | "commander": { 1059 | "version": "4.1.1", 1060 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 1061 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 1062 | "dev": true 1063 | }, 1064 | "concat-map": { 1065 | "version": "0.0.1", 1066 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1067 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1068 | "dev": true 1069 | }, 1070 | "cssesc": { 1071 | "version": "3.0.0", 1072 | "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", 1073 | "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", 1074 | "dev": true 1075 | }, 1076 | "didyoumean": { 1077 | "version": "1.2.2", 1078 | "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", 1079 | "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", 1080 | "dev": true 1081 | }, 1082 | "dlv": { 1083 | "version": "1.1.3", 1084 | "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", 1085 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", 1086 | "dev": true 1087 | }, 1088 | "fast-glob": { 1089 | "version": "3.2.12", 1090 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", 1091 | "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", 1092 | "dev": true, 1093 | "requires": { 1094 | "@nodelib/fs.stat": "^2.0.2", 1095 | "@nodelib/fs.walk": "^1.2.3", 1096 | "glob-parent": "^5.1.2", 1097 | "merge2": "^1.3.0", 1098 | "micromatch": "^4.0.4" 1099 | }, 1100 | "dependencies": { 1101 | "glob-parent": { 1102 | "version": "5.1.2", 1103 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1104 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1105 | "dev": true, 1106 | "requires": { 1107 | "is-glob": "^4.0.1" 1108 | } 1109 | } 1110 | } 1111 | }, 1112 | "fastq": { 1113 | "version": "1.15.0", 1114 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 1115 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 1116 | "dev": true, 1117 | "requires": { 1118 | "reusify": "^1.0.4" 1119 | } 1120 | }, 1121 | "fill-range": { 1122 | "version": "7.0.1", 1123 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1124 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1125 | "dev": true, 1126 | "requires": { 1127 | "to-regex-range": "^5.0.1" 1128 | } 1129 | }, 1130 | "fs.realpath": { 1131 | "version": "1.0.0", 1132 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1133 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1134 | "dev": true 1135 | }, 1136 | "fsevents": { 1137 | "version": "2.3.2", 1138 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1139 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1140 | "dev": true, 1141 | "optional": true 1142 | }, 1143 | "function-bind": { 1144 | "version": "1.1.1", 1145 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1146 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1147 | "dev": true 1148 | }, 1149 | "glob": { 1150 | "version": "7.1.6", 1151 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1152 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1153 | "dev": true, 1154 | "requires": { 1155 | "fs.realpath": "^1.0.0", 1156 | "inflight": "^1.0.4", 1157 | "inherits": "2", 1158 | "minimatch": "^3.0.4", 1159 | "once": "^1.3.0", 1160 | "path-is-absolute": "^1.0.0" 1161 | } 1162 | }, 1163 | "glob-parent": { 1164 | "version": "6.0.2", 1165 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1166 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1167 | "dev": true, 1168 | "requires": { 1169 | "is-glob": "^4.0.3" 1170 | } 1171 | }, 1172 | "has": { 1173 | "version": "1.0.3", 1174 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1175 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1176 | "dev": true, 1177 | "requires": { 1178 | "function-bind": "^1.1.1" 1179 | } 1180 | }, 1181 | "inflight": { 1182 | "version": "1.0.6", 1183 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1184 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1185 | "dev": true, 1186 | "requires": { 1187 | "once": "^1.3.0", 1188 | "wrappy": "1" 1189 | } 1190 | }, 1191 | "inherits": { 1192 | "version": "2.0.4", 1193 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1194 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1195 | "dev": true 1196 | }, 1197 | "is-binary-path": { 1198 | "version": "2.1.0", 1199 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1200 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1201 | "dev": true, 1202 | "requires": { 1203 | "binary-extensions": "^2.0.0" 1204 | } 1205 | }, 1206 | "is-core-module": { 1207 | "version": "2.11.0", 1208 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", 1209 | "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", 1210 | "dev": true, 1211 | "requires": { 1212 | "has": "^1.0.3" 1213 | } 1214 | }, 1215 | "is-extglob": { 1216 | "version": "2.1.1", 1217 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1218 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1219 | "dev": true 1220 | }, 1221 | "is-glob": { 1222 | "version": "4.0.3", 1223 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1224 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1225 | "dev": true, 1226 | "requires": { 1227 | "is-extglob": "^2.1.1" 1228 | } 1229 | }, 1230 | "is-number": { 1231 | "version": "7.0.0", 1232 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1233 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1234 | "dev": true 1235 | }, 1236 | "jiti": { 1237 | "version": "1.18.2", 1238 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", 1239 | "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", 1240 | "dev": true 1241 | }, 1242 | "lilconfig": { 1243 | "version": "2.1.0", 1244 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", 1245 | "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", 1246 | "dev": true 1247 | }, 1248 | "lines-and-columns": { 1249 | "version": "1.2.4", 1250 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 1251 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 1252 | "dev": true 1253 | }, 1254 | "merge2": { 1255 | "version": "1.4.1", 1256 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1257 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1258 | "dev": true 1259 | }, 1260 | "micromatch": { 1261 | "version": "4.0.5", 1262 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1263 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1264 | "dev": true, 1265 | "requires": { 1266 | "braces": "^3.0.2", 1267 | "picomatch": "^2.3.1" 1268 | } 1269 | }, 1270 | "minimatch": { 1271 | "version": "3.1.2", 1272 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1273 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1274 | "dev": true, 1275 | "requires": { 1276 | "brace-expansion": "^1.1.7" 1277 | } 1278 | }, 1279 | "mz": { 1280 | "version": "2.7.0", 1281 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", 1282 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", 1283 | "dev": true, 1284 | "requires": { 1285 | "any-promise": "^1.0.0", 1286 | "object-assign": "^4.0.1", 1287 | "thenify-all": "^1.0.0" 1288 | } 1289 | }, 1290 | "nanoid": { 1291 | "version": "3.3.6", 1292 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 1293 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 1294 | "dev": true 1295 | }, 1296 | "normalize-path": { 1297 | "version": "3.0.0", 1298 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1299 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1300 | "dev": true 1301 | }, 1302 | "object-assign": { 1303 | "version": "4.1.1", 1304 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1305 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1306 | "dev": true 1307 | }, 1308 | "object-hash": { 1309 | "version": "3.0.0", 1310 | "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", 1311 | "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", 1312 | "dev": true 1313 | }, 1314 | "once": { 1315 | "version": "1.4.0", 1316 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1317 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1318 | "dev": true, 1319 | "requires": { 1320 | "wrappy": "1" 1321 | } 1322 | }, 1323 | "path-is-absolute": { 1324 | "version": "1.0.1", 1325 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1326 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1327 | "dev": true 1328 | }, 1329 | "path-parse": { 1330 | "version": "1.0.7", 1331 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1332 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1333 | "dev": true 1334 | }, 1335 | "picocolors": { 1336 | "version": "1.0.0", 1337 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1338 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1339 | "dev": true 1340 | }, 1341 | "picomatch": { 1342 | "version": "2.3.1", 1343 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1344 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1345 | "dev": true 1346 | }, 1347 | "pify": { 1348 | "version": "2.3.0", 1349 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1350 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 1351 | "dev": true 1352 | }, 1353 | "pirates": { 1354 | "version": "4.0.5", 1355 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", 1356 | "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", 1357 | "dev": true 1358 | }, 1359 | "postcss": { 1360 | "version": "8.4.21", 1361 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", 1362 | "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", 1363 | "dev": true, 1364 | "requires": { 1365 | "nanoid": "^3.3.4", 1366 | "picocolors": "^1.0.0", 1367 | "source-map-js": "^1.0.2" 1368 | } 1369 | }, 1370 | "postcss-import": { 1371 | "version": "14.1.0", 1372 | "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", 1373 | "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", 1374 | "dev": true, 1375 | "requires": { 1376 | "postcss-value-parser": "^4.0.0", 1377 | "read-cache": "^1.0.0", 1378 | "resolve": "^1.1.7" 1379 | } 1380 | }, 1381 | "postcss-js": { 1382 | "version": "4.0.1", 1383 | "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", 1384 | "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", 1385 | "dev": true, 1386 | "requires": { 1387 | "camelcase-css": "^2.0.1" 1388 | } 1389 | }, 1390 | "postcss-load-config": { 1391 | "version": "3.1.4", 1392 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", 1393 | "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", 1394 | "dev": true, 1395 | "requires": { 1396 | "lilconfig": "^2.0.5", 1397 | "yaml": "^1.10.2" 1398 | } 1399 | }, 1400 | "postcss-nested": { 1401 | "version": "6.0.0", 1402 | "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", 1403 | "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", 1404 | "dev": true, 1405 | "requires": { 1406 | "postcss-selector-parser": "^6.0.10" 1407 | } 1408 | }, 1409 | "postcss-selector-parser": { 1410 | "version": "6.0.11", 1411 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", 1412 | "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", 1413 | "dev": true, 1414 | "requires": { 1415 | "cssesc": "^3.0.0", 1416 | "util-deprecate": "^1.0.2" 1417 | } 1418 | }, 1419 | "postcss-value-parser": { 1420 | "version": "4.2.0", 1421 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", 1422 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", 1423 | "dev": true 1424 | }, 1425 | "queue-microtask": { 1426 | "version": "1.2.3", 1427 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1428 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1429 | "dev": true 1430 | }, 1431 | "quick-lru": { 1432 | "version": "5.1.1", 1433 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 1434 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 1435 | "dev": true 1436 | }, 1437 | "read-cache": { 1438 | "version": "1.0.0", 1439 | "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", 1440 | "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", 1441 | "dev": true, 1442 | "requires": { 1443 | "pify": "^2.3.0" 1444 | } 1445 | }, 1446 | "readdirp": { 1447 | "version": "3.6.0", 1448 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1449 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1450 | "dev": true, 1451 | "requires": { 1452 | "picomatch": "^2.2.1" 1453 | } 1454 | }, 1455 | "resolve": { 1456 | "version": "1.22.2", 1457 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", 1458 | "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", 1459 | "dev": true, 1460 | "requires": { 1461 | "is-core-module": "^2.11.0", 1462 | "path-parse": "^1.0.7", 1463 | "supports-preserve-symlinks-flag": "^1.0.0" 1464 | } 1465 | }, 1466 | "reusify": { 1467 | "version": "1.0.4", 1468 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1469 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1470 | "dev": true 1471 | }, 1472 | "run-parallel": { 1473 | "version": "1.2.0", 1474 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1475 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1476 | "dev": true, 1477 | "requires": { 1478 | "queue-microtask": "^1.2.2" 1479 | } 1480 | }, 1481 | "source-map-js": { 1482 | "version": "1.0.2", 1483 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1484 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 1485 | "dev": true 1486 | }, 1487 | "sucrase": { 1488 | "version": "3.31.0", 1489 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.31.0.tgz", 1490 | "integrity": "sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ==", 1491 | "dev": true, 1492 | "requires": { 1493 | "commander": "^4.0.0", 1494 | "glob": "7.1.6", 1495 | "lines-and-columns": "^1.1.6", 1496 | "mz": "^2.7.0", 1497 | "pirates": "^4.0.1", 1498 | "ts-interface-checker": "^0.1.9" 1499 | } 1500 | }, 1501 | "supports-preserve-symlinks-flag": { 1502 | "version": "1.0.0", 1503 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1504 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1505 | "dev": true 1506 | }, 1507 | "tailwindcss": { 1508 | "version": "3.3.1", 1509 | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", 1510 | "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", 1511 | "dev": true, 1512 | "requires": { 1513 | "arg": "^5.0.2", 1514 | "chokidar": "^3.5.3", 1515 | "color-name": "^1.1.4", 1516 | "didyoumean": "^1.2.2", 1517 | "dlv": "^1.1.3", 1518 | "fast-glob": "^3.2.12", 1519 | "glob-parent": "^6.0.2", 1520 | "is-glob": "^4.0.3", 1521 | "jiti": "^1.17.2", 1522 | "lilconfig": "^2.0.6", 1523 | "micromatch": "^4.0.5", 1524 | "normalize-path": "^3.0.0", 1525 | "object-hash": "^3.0.0", 1526 | "picocolors": "^1.0.0", 1527 | "postcss": "^8.0.9", 1528 | "postcss-import": "^14.1.0", 1529 | "postcss-js": "^4.0.0", 1530 | "postcss-load-config": "^3.1.4", 1531 | "postcss-nested": "6.0.0", 1532 | "postcss-selector-parser": "^6.0.11", 1533 | "postcss-value-parser": "^4.2.0", 1534 | "quick-lru": "^5.1.1", 1535 | "resolve": "^1.22.1", 1536 | "sucrase": "^3.29.0" 1537 | } 1538 | }, 1539 | "thenify": { 1540 | "version": "3.3.1", 1541 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", 1542 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", 1543 | "dev": true, 1544 | "requires": { 1545 | "any-promise": "^1.0.0" 1546 | } 1547 | }, 1548 | "thenify-all": { 1549 | "version": "1.6.0", 1550 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", 1551 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", 1552 | "dev": true, 1553 | "requires": { 1554 | "thenify": ">= 3.1.0 < 4" 1555 | } 1556 | }, 1557 | "to-regex-range": { 1558 | "version": "5.0.1", 1559 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1560 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1561 | "dev": true, 1562 | "requires": { 1563 | "is-number": "^7.0.0" 1564 | } 1565 | }, 1566 | "ts-interface-checker": { 1567 | "version": "0.1.13", 1568 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", 1569 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", 1570 | "dev": true 1571 | }, 1572 | "util-deprecate": { 1573 | "version": "1.0.2", 1574 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1575 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 1576 | "dev": true 1577 | }, 1578 | "wrappy": { 1579 | "version": "1.0.2", 1580 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1581 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1582 | "dev": true 1583 | }, 1584 | "yaml": { 1585 | "version": "1.10.2", 1586 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 1587 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 1588 | "dev": true 1589 | } 1590 | } 1591 | } 1592 | --------------------------------------------------------------------------------