diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000..ef2ddb0 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,15 @@ +version = 1 + +[[analyzers]] +name = "javascript" +enabled = true + + [analyzers.meta] + plugins = ["angular"] + +[[analyzers]] +name = "rust" +enabled = true + + [analyzers.meta] + msrv = "1.30.0" diff --git a/mediarepo-api/Cargo.toml b/mediarepo-api/Cargo.toml index 522a42f..2f03658 100644 --- a/mediarepo-api/Cargo.toml +++ b/mediarepo-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mediarepo-api" -version = "0.28.1" +version = "0.31.0" edition = "2018" license = "gpl-3" @@ -15,12 +15,12 @@ serde_json = { version = "1.0.78", optional = true } directories = { version = "4.0.1", optional = true } mime_guess = { version = "2.0.3", optional = true } serde_piecewise_default = "0.2.0" -futures = { version = "0.3.19", optional = true } +futures = { version = "0.3.21", optional = true } url = { version = "2.2.2", optional = true } pathsearch = { version = "0.2.0", optional = true } [dependencies.bromine] -version = "0.17.1" +version = "0.18.1" optional = true features = ["serialize_bincode"] diff --git a/mediarepo-api/src/client_api/error.rs b/mediarepo-api/src/client_api/error.rs index f5e9e05..24b6c55 100644 --- a/mediarepo-api/src/client_api/error.rs +++ b/mediarepo-api/src/client_api/error.rs @@ -10,3 +10,6 @@ pub enum ApiError { #[error("The servers api version (version {server:?}) is incompatible with the api client {client:?}")] VersionMismatch { server: String, client: String }, } + +unsafe impl Send for ApiError {} +unsafe impl Sync for ApiError {} diff --git a/mediarepo-api/src/client_api/file.rs b/mediarepo-api/src/client_api/file.rs index b0fb29b..4ef363a 100644 --- a/mediarepo-api/src/client_api/file.rs +++ b/mediarepo-api/src/client_api/file.rs @@ -153,8 +153,11 @@ impl FileApi { /// Permanently deletes a file from the disk and database #[tracing::instrument(level = "debug", skip(self))] pub async fn delete_file(&self, file_id: FileIdentifier) -> ApiResult<()> { - self.emit_and_get("delete_file", file_id, Some(Duration::from_secs(10))) - .await + self.emit("delete_file", file_id) + .await_reply() + .await?; + + Ok(()) } /// Returns a list of all thumbnails of the file @@ -198,7 +201,7 @@ impl FileApi { /// Deletes all thumbnails of a file to regenerate them when requested #[tracing::instrument(level = "debug", skip(self))] pub async fn delete_thumbnails(&self, file_id: FileIdentifier) -> ApiResult<()> { - self.emit("delete_thumbnails", file_id).await?; + self.emit("delete_thumbnails", file_id).await_reply().await?; Ok(()) } diff --git a/mediarepo-api/src/client_api/job.rs b/mediarepo-api/src/client_api/job.rs index fe05ac8..cfbe8d1 100644 --- a/mediarepo-api/src/client_api/job.rs +++ b/mediarepo-api/src/client_api/job.rs @@ -26,15 +26,12 @@ impl JobApi { /// Runs a job of the given type and returns when it has finished #[tracing::instrument(level = "debug", skip(self))] - pub async fn run_job(&self, job_type: JobType) -> ApiResult<()> { - self.emit_and_get( - "run_job", - RunJobRequest { - job_type, - sync: true, - }, - Some(Duration::from_secs(3600)), - ) - .await + pub async fn run_job(&self, job_type: JobType, sync: bool) -> ApiResult<()> { + self.emit("run_job", RunJobRequest { job_type, sync }) + .await_reply() + .with_timeout(Duration::from_secs(3600)) + .await?; + + Ok(()) } } diff --git a/mediarepo-api/src/client_api/mod.rs b/mediarepo-api/src/client_api/mod.rs index 3dfbcab..787ed0c 100644 --- a/mediarepo-api/src/client_api/mod.rs +++ b/mediarepo-api/src/client_api/mod.rs @@ -13,8 +13,8 @@ use crate::client_api::repo::RepoApi; use crate::client_api::tag::TagApi; use crate::types::misc::{check_apis_compatible, get_api_version, InfoResponse}; use async_trait::async_trait; -use bromine::ipc::stream_emitter::EmitMetadata; use bromine::prelude::*; +use bromine::prelude::emit_metadata::EmitMetadata; use tokio::time::Duration; use crate::client_api::preset::PresetApi; @@ -84,12 +84,14 @@ impl ApiClient { pub async fn connect( address: L::AddressType, ) -> ApiResult { + tracing::debug!("Connecting to {:?}", address); let ctx = IPCBuilder::::new() .address(address) .timeout(Duration::from_secs(10)) .build_pooled_client(8) .await?; let client = Self::new(ctx); + tracing::debug!("Retrieving info on daemon version..."); let info = client.info().await?; let server_api_version = info.api_version(); @@ -113,6 +115,8 @@ impl ApiClient { pub async fn info(&self) -> ApiResult { let ctx = self.ctx.acquire(); let res = ctx.emit("info", ()).await_reply().await?; + tracing::trace!("Got info event {:?}", res); + Ok(res.payload::()?) } diff --git a/mediarepo-api/src/client_api/preset.rs b/mediarepo-api/src/client_api/preset.rs index 31beaa6..3a3bef2 100644 --- a/mediarepo-api/src/client_api/preset.rs +++ b/mediarepo-api/src/client_api/preset.rs @@ -1,8 +1,8 @@ -use std::time::Duration; -use bromine::prelude::*; -use crate::client_api::error::ApiResult; -use crate::types::filtering::{SortingPreset, SortKey}; use super::IPCApi; +use crate::client_api::error::ApiResult; +use crate::types::filtering::{SortKey, SortingPreset}; +use bromine::prelude::*; +use std::time::Duration; #[derive(Clone)] pub struct PresetApi { @@ -27,28 +27,22 @@ impl PresetApi { /// Returns all sorting presets of the repository #[tracing::instrument(level = "debug", skip(self))] pub async fn all_sorting_presets(&self) -> ApiResult> { - self.emit_and_get( - "all_sorting_presets", - (), - Some(Duration::from_secs(1)) - ) + self.emit_and_get("all_sorting_presets", (), Some(Duration::from_secs(1))) .await } /// Adds a new sorting preset with the given keys #[tracing::instrument(level = "debug", skip(self))] pub async fn add_sorting_preset(&self, keys: Vec) -> ApiResult { - self.emit_and_get( - "add_sorting_preset", - keys, - Some(Duration::from_secs(1)) - ) + self.emit_and_get("add_sorting_preset", keys, Some(Duration::from_secs(1))) .await } /// Deletes a given sorting preset by id #[tracing::instrument(level = "debug", skip(self))] pub async fn delete_sorting_preset(&self, id: i32) -> ApiResult<()> { - self.emit_and_get("delete_sorting_preset", id, Some(Duration::from_secs(1))).await + self.emit("delete_sorting_preset", id).await_reply().await?; + + Ok(()) } } diff --git a/mediarepo-api/src/tauri_plugin/background_tasks.rs b/mediarepo-api/src/tauri_plugin/background_tasks.rs new file mode 100644 index 0000000..0035799 --- /dev/null +++ b/mediarepo-api/src/tauri_plugin/background_tasks.rs @@ -0,0 +1,158 @@ +use crate::tauri_plugin::error::{PluginError, PluginResult}; +use futures::future; +use std::collections::HashMap; +use std::fmt::{Debug, Formatter}; +use std::future::Future; +use std::pin::Pin; +use std::sync::Arc; +use std::time::{Duration, SystemTime}; +use std::{mem, thread}; +use tokio::sync::{Mutex, RwLock}; + +#[derive(Clone, Debug)] +pub struct TaskContext { + tasks: Arc>>, +} + +impl TaskContext { + pub fn new() -> Self { + Self { + tasks: Default::default(), + } + } + + pub async fn add_task>>( + &self, + name: S, + task: F, + ) { + self.tasks + .write() + .await + .insert(name.to_string(), AsyncTask::new(task)); + } + + pub async fn task_state>(&self, name: S) -> Option { + let state = { + let tasks = self.tasks.read().await; + + if let Some(task) = tasks.get(name.as_ref()) { + Some(task.state().await) + } else { + None + } + }; + if let Some(TaskState::Finished) = state { + self.tasks.write().await.remove(name.as_ref()); + } + + state + } + + /// Returns all tasks queued for execution + async fn queued_tasks(&self) -> Vec { + let task_map = self.tasks.read().await; + let mut tasks = Vec::new(); + + for task in task_map.values() { + if task.state().await == TaskState::Queued { + tasks.push(task.clone()); + } + } + + tasks + } +} + +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +pub enum TaskState { + Queued, + Running, + Finished, + Error, +} + +impl TaskState { + pub fn error(&self) -> bool { + *self == TaskState::Error + } +} + +#[derive(Clone)] +pub struct AsyncTask { + state: Arc>, + inner: Arc>>>>>>, + error: Arc>>, +} + +impl Debug for AsyncTask { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "AsyncTask (state: {:?})", self.state) + } +} + +impl AsyncTask { + pub fn new>>(inner: F) -> Self { + Self { + state: Arc::new(RwLock::new(TaskState::Queued)), + inner: Arc::new(Mutex::new(Some(Box::pin(inner)))), + error: Default::default(), + } + } + + pub async fn exec(&self) { + self.set_state(TaskState::Running).await; + + let inner = self.inner.lock().await.take(); + if let Some(task) = inner { + if let Err(e) = task.await { + let _ = mem::replace(&mut *self.error.write().await, Some(e)); + self.set_state(TaskState::Error).await; + } else { + self.set_state(TaskState::Finished).await; + } + } else { + self.set_state(TaskState::Finished).await; + } + } + + pub async fn state(&self) -> TaskState { + self.state.read().await.clone() + } + + async fn set_state(&self, state: TaskState) { + let _ = mem::replace(&mut *self.state.write().await, state); + } +} + +unsafe impl Send for AsyncTask {} +unsafe impl Sync for AsyncTask {} + +pub fn start_background_task_runtime(ctx: TaskContext) { + thread::spawn(move || { + tokio::runtime::Builder::new_current_thread() + .thread_name("background_tasks") + .enable_time() + .build() + .expect("failed to build background task runtime") + .block_on(async move { + tracing::debug!("background task listener ready"); + loop { + let tasks = ctx.queued_tasks().await; + + if tasks.len() > 0 { + tracing::debug!("executing {} async background tasks", tasks.len()); + let start = SystemTime::now(); + future::join_all(tasks.iter().map(|t| t.exec())).await; + tracing::debug!( + "background tasks executed in {} ms", + start.elapsed().unwrap().as_millis() + ); + } else { + tokio::time::sleep(Duration::from_millis(100)).await; + } + } + }); + tracing::error!("background task executor exited!"); + }); +} diff --git a/mediarepo-api/src/tauri_plugin/commands/job.rs b/mediarepo-api/src/tauri_plugin/commands/job.rs index 8866b8b..313e613 100644 --- a/mediarepo-api/src/tauri_plugin/commands/job.rs +++ b/mediarepo-api/src/tauri_plugin/commands/job.rs @@ -3,9 +3,9 @@ use crate::tauri_plugin::error::PluginResult; use crate::types::jobs::JobType; #[tauri::command] -pub async fn run_job(api_state: ApiAccess<'_>, job_type: JobType) -> PluginResult<()> { +pub async fn run_job(api_state: ApiAccess<'_>, job_type: JobType, sync: bool) -> PluginResult<()> { let api = api_state.api().await?; - api.job.run_job(job_type).await?; + api.job.run_job(job_type, sync).await?; Ok(()) } diff --git a/mediarepo-api/src/tauri_plugin/custom_schemes.rs b/mediarepo-api/src/tauri_plugin/custom_schemes.rs index 436b8f4..8941b4a 100644 --- a/mediarepo-api/src/tauri_plugin/custom_schemes.rs +++ b/mediarepo-api/src/tauri_plugin/custom_schemes.rs @@ -1,3 +1,5 @@ +use crate::client_api::ApiClient; +use crate::tauri_plugin::background_tasks::TaskContext; use crate::tauri_plugin::error::{PluginError, PluginResult}; use crate::tauri_plugin::state::{ApiState, BufferState}; use crate::types::identifier::FileIdentifier; @@ -5,7 +7,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; use tauri::http::{Request, Response, ResponseBuilder}; -use tauri::{AppHandle, Builder, Manager, Runtime}; +use tauri::{AppHandle, Builder, Manager, Runtime, State}; use tokio::runtime::{Builder as TokioRuntimeBuilder, Runtime as TokioRuntime}; use url::Url; @@ -54,7 +56,6 @@ fn once_scheme(app: &AppHandle, request: &Request) -> Result(app: &AppHandle, request: &Request) -> Result { - let api_state = app.state::(); let buf_state = app.state::(); let hash = request.uri().trim_start_matches("content://"); @@ -66,7 +67,10 @@ async fn content_scheme(app: &AppHandle, request: &Request) -> Re .body(buffer.buf) } else { tracing::debug!("Fetching content from daemon"); + + let api_state = app.state::(); let api = api_state.api().await?; + let file = api .file .get_file(FileIdentifier::CD(hash.to_string())) @@ -78,16 +82,16 @@ async fn content_scheme(app: &AppHandle, request: &Request) -> Re .await?; tracing::debug!("Received {} content bytes", bytes.len()); buf_state.add_entry(hash.to_string(), mime.clone(), bytes.clone()); + ResponseBuilder::new() - .mimetype(&mime) .status(200) + .mimetype(&mime) .body(bytes) } } #[tracing::instrument(level = "debug", skip_all)] async fn thumb_scheme(app: &AppHandle, request: &Request) -> Result { - let api_state = app.state::(); let buf_state = app.state::(); let url = Url::parse(request.uri())?; @@ -116,26 +120,62 @@ async fn thumb_scheme(app: &AppHandle, request: &Request) -> Resu .mimetype(&buffer.mime) .body(buffer.buf) } else { - tracing::debug!("Fetching content from daemon"); - let api = api_state.api().await?; - let (thumb, bytes) = api - .file - .get_thumbnail_of_size( - FileIdentifier::CD(hash.to_string()), - ((height as f32 * 0.8) as u32, (width as f32 * 0.8) as u32), - ((height as f32 * 1.2) as u32, (width as f32 * 1.2) as u32), + tracing::debug!("Content not loaded. Signaling retry."); + let task_ctx = app.state::(); + + let state = task_ctx.task_state(request.uri()).await; + + if state.is_none() || state.unwrap().error() { + let buf_state = buf_state.inner().clone(); + let api_state = app.state::(); + let api = api_state.api().await?; + + add_fetch_thumbnail_task( + request.uri(), + task_ctx, + buf_state, + api, + hash.to_string(), + request.uri().to_string(), + width, + height, ) - .await?; - tracing::debug!("Received {} content bytes", bytes.len()); - buf_state.add_entry( - request.uri().to_string(), - thumb.mime_type.clone(), - bytes.clone(), - ); + .await; + } ResponseBuilder::new() - .mimetype(&thumb.mime_type) - .status(200) - .body(bytes) + .mimetype("text/plain") + .status(301) + .header("Retry-After", "1") + .body("Content loading. Retry in 1s.".as_bytes().to_vec()) } } + +async fn add_fetch_thumbnail_task( + name: &str, + task_ctx: State<'_, TaskContext>, + buf_state: BufferState, + api: ApiClient, + hash: String, + request_uri: String, + width: u32, + height: u32, +) { + task_ctx + .add_task(name, async move { + tracing::debug!("Fetching content from daemon"); + let (thumb, bytes) = api + .file + .get_thumbnail_of_size( + FileIdentifier::CD(hash), + ((height as f32 * 0.5) as u32, (width as f32 * 0.5) as u32), + ((height as f32 * 1.5) as u32, (width as f32 * 1.5) as u32), + ) + .await?; + tracing::debug!("Received {} content bytes", bytes.len()); + buf_state.add_entry(request_uri, thumb.mime_type.clone(), bytes.clone()); + + Ok(()) + }) + .await; +} diff --git a/mediarepo-api/src/tauri_plugin/mod.rs b/mediarepo-api/src/tauri_plugin/mod.rs index 7a570a7..85e581a 100644 --- a/mediarepo-api/src/tauri_plugin/mod.rs +++ b/mediarepo-api/src/tauri_plugin/mod.rs @@ -7,6 +7,7 @@ use crate::tauri_plugin::state::{AppState, BufferState}; use std::thread; use std::time::Duration; +mod background_tasks; pub(crate) mod commands; pub mod custom_schemes; pub mod error; @@ -14,9 +15,10 @@ mod settings; mod state; mod utils; +use crate::tauri_plugin::background_tasks::{start_background_task_runtime, TaskContext}; use commands::*; -const MAX_BUFFER_SIZE: usize = 2 * 1024 * 1024 * 1024; +const MAX_BUFFER_SIZE: usize = 2 * 1024 * 1024 * 1024; // 2GiB pub fn register_plugin(builder: Builder) -> Builder { let repo_plugin = MediarepoPlugin::new(); @@ -99,6 +101,10 @@ impl Plugin for MediarepoPlugin { let repo_state = AppState::load()?; app.manage(repo_state); + let task_context = TaskContext::new(); + start_background_task_runtime(task_context.clone()); + app.manage(task_context); + thread::spawn(move || loop { thread::sleep(Duration::from_secs(10)); buffer_state.clear_expired(); diff --git a/mediarepo-api/src/types/files.rs b/mediarepo-api/src/types/files.rs index ff9153e..d6f5cec 100644 --- a/mediarepo-api/src/types/files.rs +++ b/mediarepo-api/src/types/files.rs @@ -58,6 +58,7 @@ pub struct FileMetadataResponse { pub creation_time: NaiveDateTime, pub change_time: NaiveDateTime, pub import_time: NaiveDateTime, + pub size: u64, } #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/mediarepo-api/src/types/jobs.rs b/mediarepo-api/src/types/jobs.rs index e8b9d3b..6cbed1a 100644 --- a/mediarepo-api/src/types/jobs.rs +++ b/mediarepo-api/src/types/jobs.rs @@ -10,6 +10,7 @@ pub struct RunJobRequest { pub enum JobType { MigrateContentDescriptors, CalculateSizes, + GenerateThumbnails, CheckIntegrity, Vacuum, } diff --git a/mediarepo-daemon/Cargo.lock b/mediarepo-daemon/Cargo.lock index a36a12b..09f9992 100644 --- a/mediarepo-daemon/Cargo.lock +++ b/mediarepo-daemon/Cargo.lock @@ -269,15 +269,16 @@ dependencies = [ [[package]] name = "bromine" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6774171be092328d9631f246d3122f196a50ddaad224214ca274acec2a1db65d" +checksum = "5dd7887995490657bf3ec578f39e747ef7b5355a8dc6c99b3d5be59ca70dc4d5" dependencies = [ "async-trait", "bincode", "byteorder", - "futures 0.3.19", + "futures-core", "lazy_static", + "num_enum", "serde 1.0.136", "thiserror", "tokio", @@ -428,7 +429,7 @@ checksum = "829835c211a0247cd11e65e13cec8696b879374879c35ce162ce8098b23c90d4" dependencies = [ "console-api", "crossbeam-channel", - "futures 0.3.19", + "futures 0.3.21", "hdrhistogram", "humantime", "serde 1.0.136", @@ -840,9 +841,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -855,9 +856,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -865,15 +866,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -893,15 +894,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2 1.0.36", "quote 1.0.15", @@ -910,21 +911,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -1360,7 +1361,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mediarepo-api" -version = "0.28.1" +version = "0.31.0" dependencies = [ "bromine", "chrono", @@ -1377,7 +1378,7 @@ dependencies = [ "base64", "config", "data-encoding", - "futures 0.3.19", + "futures 0.3.21", "glob", "itertools", "mediarepo-api", @@ -1397,7 +1398,7 @@ dependencies = [ [[package]] name = "mediarepo-daemon" -version = "0.13.4" +version = "1.0.0-rc.1" dependencies = [ "console-subscriber", "glob", @@ -1708,6 +1709,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.36", + "quote 1.0.15", + "syn 1.0.86", +] + [[package]] name = "num_threads" version = "0.1.3" @@ -2196,14 +2218,14 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sea-orm" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5452736ac11d11f9dcf1980897d3a6302d78ee2bfcb928b0f9c03569f2e6b12c" +checksum = "dd24380b48dacd3ed1c3d467c7b17ffa5818555a2c04066f4a0a9e17d830abc9" dependencies = [ "async-stream", "async-trait", "chrono", - "futures 0.3.19", + "futures 0.3.21", "futures-util", "once_cell", "ouroboros", @@ -2221,9 +2243,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8b7b6d423b591bf447685e9ea7cecd65e0c282e18dc5ddc7438425cd296faa8" +checksum = "c199fa8630b1e195d7aef24ce8944af8f4ced67c4eccffd8926453b59f2565a1" dependencies = [ "bae", "heck", @@ -2234,9 +2256,9 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83e4a0dd79545b61c6ca453a28d0a88829487869a8559a35a3192f1b6aacad8" +checksum = "9088ff96158860a75d98a85a654fdd9d97b10515773af6d87339bfc48258c800" dependencies = [ "chrono", "rust_decimal", @@ -2812,7 +2834,7 @@ checksum = "d08ebea7dc6b22273290d8ece2ca448f979f836e38ba629b650595c64204b4f2" dependencies = [ "anyhow", "async-recursion", - "futures 0.3.19", + "futures 0.3.21", "log", "tokio", "tokio-util", diff --git a/mediarepo-daemon/Cargo.toml b/mediarepo-daemon/Cargo.toml index 54623a3..154a47a 100644 --- a/mediarepo-daemon/Cargo.toml +++ b/mediarepo-daemon/Cargo.toml @@ -4,7 +4,7 @@ default-members = ["mediarepo-core", "mediarepo-database", "mediarepo-logic", "m [package] name = "mediarepo-daemon" -version = "0.13.4" +version = "1.0.0-rc.1" edition = "2018" license = "gpl-3" repository = "https://github.com/Trivernis/mediarepo-daemon" diff --git a/mediarepo-daemon/mediarepo-core/Cargo.toml b/mediarepo-daemon/mediarepo-core/Cargo.toml index 75034c6..3ff010b 100644 --- a/mediarepo-daemon/mediarepo-core/Cargo.toml +++ b/mediarepo-daemon/mediarepo-core/Cargo.toml @@ -14,7 +14,7 @@ base64 = "0.13.0" toml = "0.5.8" serde = "1.0.136" typemap_rev = "0.1.5" -futures = "0.3.19" +futures = "0.3.21" itertools = "0.10.3" glob = "0.3.0" tracing = "0.1.30" @@ -26,7 +26,7 @@ version = "0.3.0" default-features = false [dependencies.sea-orm] -version = "0.5.0" +version = "0.6.0" default-features = false [dependencies.sqlx] diff --git a/mediarepo-daemon/mediarepo-core/src/utils.rs b/mediarepo-daemon/mediarepo-core/src/utils.rs index 4d901e8..c65a638 100644 --- a/mediarepo-daemon/mediarepo-core/src/utils.rs +++ b/mediarepo-daemon/mediarepo-core/src/utils.rs @@ -9,6 +9,7 @@ use crate::error::RepoResult; /// Parses a normalized tag into its two components of namespace and tag pub fn parse_namespace_and_tag(norm_tag: String) -> (Option, String) { norm_tag + .to_lowercase() .split_once(':') .map(|(n, t)| (Some(n.trim().to_string()), t.trim().to_string())) .unwrap_or((None, norm_tag.trim().to_string())) @@ -49,10 +50,7 @@ pub async fn get_folder_size(path: PathBuf) -> RepoResult { let futures = all_files.into_iter().map(|f| read_file_size(f)); let results = future::join_all(futures).await; - let size = results - .into_iter() - .filter_map(|r| r.ok()) - .fold(0u64, |acc, val| acc + val); + let size = results.into_iter().filter_map(|r| r.ok()).sum(); Ok(size) } diff --git a/mediarepo-daemon/mediarepo-database/Cargo.toml b/mediarepo-daemon/mediarepo-database/Cargo.toml index 1e79ee4..52c3dfc 100644 --- a/mediarepo-daemon/mediarepo-database/Cargo.toml +++ b/mediarepo-daemon/mediarepo-database/Cargo.toml @@ -18,6 +18,6 @@ version = "0.5.10" features = ["migrate"] [dependencies.sea-orm] -version = "0.5.0" +version = "0.6.0" features = ["sqlx-sqlite", "runtime-tokio-native-tls", "macros", "debug-print"] default-features = false diff --git a/mediarepo-daemon/mediarepo-logic/Cargo.toml b/mediarepo-daemon/mediarepo-logic/Cargo.toml index 08a02e6..3c2292c 100644 --- a/mediarepo-daemon/mediarepo-logic/Cargo.toml +++ b/mediarepo-daemon/mediarepo-logic/Cargo.toml @@ -22,7 +22,7 @@ path = "../mediarepo-core" path = "../mediarepo-database" [dependencies.sea-orm] -version = "0.5.0" +version = "0.6.0" features = ["runtime-tokio-native-tls", "macros"] default-features = false diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/file/add.rs b/mediarepo-daemon/mediarepo-logic/src/dao/file/add.rs index 6bb93c8..e3be978 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/file/add.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/file/add.rs @@ -2,9 +2,10 @@ use std::io::Cursor; use chrono::{Local, NaiveDateTime}; use sea_orm::ActiveValue::Set; -use sea_orm::{ActiveModelTrait, ConnectionTrait, DatabaseTransaction}; +use sea_orm::{ActiveModelTrait, DatabaseTransaction, TransactionTrait}; use mediarepo_core::error::RepoResult; +use mediarepo_core::thumbnailer::ThumbnailSize; use mediarepo_database::entities::{content_descriptor, file, file_metadata}; use crate::dao::file::FileDao; @@ -44,8 +45,11 @@ impl FileDao { .await?; trx.commit().await?; + let dto = FileDto::new(file, cd, Some(metadata)); + self.create_thumbnails(&dto, vec![ThumbnailSize::Medium]) + .await?; - Ok(FileDto::new(file, cd, Some(metadata))) + Ok(dto) } } diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/file/delete.rs b/mediarepo-daemon/mediarepo-logic/src/dao/file/delete.rs index 81c914a..b9c0dac 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/file/delete.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/file/delete.rs @@ -1,12 +1,12 @@ -use sea_orm::ConnectionTrait; use sea_orm::prelude::*; +use sea_orm::TransactionTrait; -use mediarepo_core::error::{RepoResult}; +use mediarepo_core::error::RepoResult; use mediarepo_database::entities::{ content_descriptor, content_descriptor_tag, file, file_metadata, }; -use crate::dao::file::{FileDao}; +use crate::dao::file::FileDao; use crate::dto::FileDto; impl FileDao { diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/file/update.rs b/mediarepo-daemon/mediarepo-logic/src/dao/file/update.rs index 1f554fa..184bf1b 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/file/update.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/file/update.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use sea_orm::prelude::*; use sea_orm::ActiveValue::{Set, Unchanged}; -use sea_orm::{ConnectionTrait, NotSet}; +use sea_orm::{NotSet, TransactionTrait}; use mediarepo_core::error::{RepoError, RepoResult}; use mediarepo_core::fs::thumbnail_store::Dimensions; @@ -58,7 +58,7 @@ impl FileDao { #[tracing::instrument(level = "debug", skip(self))] pub async fn create_thumbnails + Debug>( &self, - file: FileDto, + file: &FileDto, sizes: I, ) -> RepoResult> { let bytes = self.get_bytes(file.cd()).await?; diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs new file mode 100644 index 0000000..e4f9899 --- /dev/null +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs @@ -0,0 +1,31 @@ +use crate::dao::job::JobDao; +use crate::dao::DaoProvider; +use mediarepo_core::error::RepoResult; +use mediarepo_core::futures; +use mediarepo_core::thumbnailer::ThumbnailSize; + +impl JobDao { + /// Generates thumbnails for files that are still missing some + #[tracing::instrument(level = "debug", skip(self))] + pub async fn generate_missing_thumbnails(&self) -> RepoResult<()> { + let file_dao = self.file(); + let files = file_dao.all().await?; + let mut missing_thumbnails = Vec::new(); + + for file in files { + if file_dao.thumbnails(file.encoded_cd()).await?.is_empty() { + missing_thumbnails.push(file); + } + } + + futures::future::join_all(missing_thumbnails.into_iter().map(|f| async { + let file = f; + file_dao + .create_thumbnails(&file, vec![ThumbnailSize::Medium]) + .await + })) + .await; + + Ok(()) + } +} diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs index 6c395fe..e0683b0 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/migrate_content_descriptors.rs @@ -6,7 +6,7 @@ use mediarepo_core::error::RepoResult; use mediarepo_database::entities::content_descriptor; use sea_orm::prelude::*; use sea_orm::ActiveValue::Set; -use sea_orm::ConnectionTrait; +use sea_orm::TransactionTrait; impl JobDao { #[tracing::instrument(level = "debug", skip(self))] diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs index 16bace3..31ab290 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs @@ -1,5 +1,6 @@ use crate::dao_provider; +pub mod generate_missing_thumbnails; pub mod migrate_content_descriptors; pub mod sqlite_operations; diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs index 81c8aeb..39a4b96 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/sorting_preset/add.rs @@ -5,8 +5,8 @@ use mediarepo_database::entities::{sort_key, sorting_preset, sorting_preset_key} use sea_orm::prelude::*; use sea_orm::ActiveValue::Set; use sea_orm::{ - Condition, ConnectionTrait, DatabaseTransaction, DbBackend, FromQueryResult, JoinType, - QuerySelect, Statement, + Condition, DatabaseTransaction, DbBackend, FromQueryResult, JoinType, QuerySelect, Statement, + TransactionTrait, }; #[allow(unused_imports)] diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/tag/add.rs b/mediarepo-daemon/mediarepo-logic/src/dao/tag/add.rs index e910fe5..4db54b2 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/tag/add.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/tag/add.rs @@ -4,7 +4,7 @@ use mediarepo_core::error::RepoResult; use mediarepo_database::entities::{namespace, tag}; use sea_orm::prelude::*; use sea_orm::ActiveValue::Set; -use sea_orm::{Condition, ConnectionTrait, DatabaseTransaction}; +use sea_orm::{Condition, DatabaseTransaction, TransactionTrait}; use std::collections::HashMap; use std::iter::FromIterator; diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/tag/mappings.rs b/mediarepo-daemon/mediarepo-logic/src/dao/tag/mappings.rs index 0e2f488..ac9f26c 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/tag/mappings.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/tag/mappings.rs @@ -1,6 +1,6 @@ -use sea_orm::{ConnectionTrait, DatabaseTransaction}; -use sea_orm::ActiveValue::Set; use sea_orm::prelude::*; +use sea_orm::ActiveValue::Set; +use sea_orm::{DatabaseTransaction, TransactionTrait}; use mediarepo_core::error::RepoResult; use mediarepo_database::entities::content_descriptor_tag; @@ -28,11 +28,13 @@ impl TagDao { }) .collect(); - content_descriptor_tag::Entity::insert_many(active_models) - .exec(&trx) - .await?; + if !active_models.is_empty() { + content_descriptor_tag::Entity::insert_many(active_models) + .exec(&trx) + .await?; - trx.commit().await?; + trx.commit().await?; + } Ok(()) } @@ -60,7 +62,7 @@ async fn get_existing_mappings( .all(trx) .await? .into_iter() - .map(|model: content_descriptor_tag::Model| (model.tag_id, model.cd_id)) + .map(|model: content_descriptor_tag::Model| (model.cd_id, model.tag_id)) .collect(); Ok(existing_mappings) } diff --git a/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs b/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs index 2729ecc..50d7b0a 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs @@ -7,7 +7,7 @@ pub struct NamespaceDto { impl NamespaceDto { pub(crate) fn new(model: namespace::Model) -> Self { - Self {model} + Self { model } } pub fn id(&self) -> i64 { @@ -17,4 +17,4 @@ impl NamespaceDto { pub fn name(&self) -> &String { &self.model.name } -} \ No newline at end of file +} diff --git a/mediarepo-daemon/mediarepo-socket/src/from_model.rs b/mediarepo-daemon/mediarepo-socket/src/from_model.rs index bf101e9..b241096 100644 --- a/mediarepo-daemon/mediarepo-socket/src/from_model.rs +++ b/mediarepo-daemon/mediarepo-socket/src/from_model.rs @@ -23,6 +23,7 @@ impl FromModel for FileMetadataResponse { creation_time: model.creation_time().to_owned(), change_time: model.change_time().to_owned(), import_time: model.import_time().to_owned(), + size: model.size() as u64, } } } diff --git a/mediarepo-daemon/mediarepo-socket/src/lib.rs b/mediarepo-daemon/mediarepo-socket/src/lib.rs index 4979eda..b8efdfe 100644 --- a/mediarepo-daemon/mediarepo-socket/src/lib.rs +++ b/mediarepo-daemon/mediarepo-socket/src/lib.rs @@ -96,18 +96,17 @@ fn get_builder(address: L::AddressType) -> IPCBu } #[tracing::instrument(skip_all)] -async fn info(ctx: &Context, _: Event) -> IPCResult<()> { +async fn info(ctx: &Context, _: Event) -> IPCResult { let response = InfoResponse::new( env!("CARGO_PKG_NAME").to_string(), env!("CARGO_PKG_VERSION").to_string(), ); - ctx.emit("info", response).await?; - Ok(()) + ctx.response(response) } #[tracing::instrument(skip_all)] -async fn shutdown(ctx: &Context, _: Event) -> IPCResult<()> { +async fn shutdown(ctx: &Context, _: Event) -> IPCResult { ctx.clone().stop().await?; { let data = ctx.data.read().await; @@ -115,7 +114,6 @@ async fn shutdown(ctx: &Context, _: Event) -> IPCResult<()> { subsystem.request_shutdown(); subsystem.on_shutdown_requested().await; } - ctx.emit("shutdown", ()).await?; - Ok(()) + Ok(Response::empty()) } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs index 339b6bd..2c02703 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/files/mod.rs @@ -54,7 +54,7 @@ impl NamespaceProvider for FilesNamespace { impl FilesNamespace { /// Returns a list of all files #[tracing::instrument(skip_all)] - async fn all_files(ctx: &Context, _event: Event) -> IPCResult<()> { + async fn all_files(ctx: &Context, _event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let files = repo.file().all().await?; @@ -63,26 +63,23 @@ impl FilesNamespace { .map(FileBasicDataResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "all_files", responses).await?; - - Ok(()) + ctx.response(responses) } /// Returns a file by id #[tracing::instrument(skip_all)] - async fn get_file(ctx: &Context, event: Event) -> IPCResult<()> { + async fn get_file(ctx: &Context, event: Event) -> IPCResult { let id = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file = file_by_identifier(id, &repo).await?; let response = FileBasicDataResponse::from_model(file); - ctx.emit_to(Self::name(), "get_file", response).await?; - Ok(()) + ctx.response(response) } /// Returns metadata for a given file #[tracing::instrument(skip_all)] - async fn get_file_metadata(ctx: &Context, event: Event) -> IPCResult<()> { + async fn get_file_metadata(ctx: &Context, event: Event) -> IPCResult { let id = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file = file_by_identifier(id, &repo).await?; @@ -97,19 +94,12 @@ impl FilesNamespace { .ok_or_else(|| RepoError::from("file metadata not found"))? }; - ctx.emit_to( - Self::name(), - "get_file_metadata", - FileMetadataResponse::from_model(metadata), - ) - .await?; - - Ok(()) + ctx.response(FileMetadataResponse::from_model(metadata)) } /// Returns a list of files by identifier #[tracing::instrument(skip_all)] - async fn get_files(ctx: &Context, event: Event) -> IPCResult<()> { + async fn get_files(ctx: &Context, event: Event) -> IPCResult { let ids = event.payload::>()?; let repo = get_repo_from_context(ctx).await; let mut responses = Vec::new(); @@ -121,14 +111,13 @@ impl FilesNamespace { .map(FileBasicDataResponse::from_model)?, ); } - ctx.emit_to(Self::name(), "get_files", responses).await?; - Ok(()) + ctx.response(responses) } /// Searches for files by tags #[tracing::instrument(skip_all)] - async fn find_files(ctx: &Context, event: Event) -> IPCResult<()> { + async fn find_files(ctx: &Context, event: Event) -> IPCResult { let req = event.payload::()?; let repo = get_repo_from_context(ctx).await; @@ -139,13 +128,13 @@ impl FilesNamespace { .into_iter() .map(FileBasicDataResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "find_files", responses).await?; - Ok(()) + + ctx.response(responses) } /// Adds a file to the repository #[tracing::instrument(skip_all)] - async fn add_file(ctx: &Context, event: Event) -> IPCResult<()> { + async fn add_file(ctx: &Context, event: Event) -> IPCResult { let (request, bytes) = event .payload::>()? .into_inner(); @@ -184,18 +173,11 @@ impl FilesNamespace { .upsert_mappings(vec![file.cd_id()], tag_ids) .await?; - ctx.emit_to( - Self::name(), - "add_file", - FileBasicDataResponse::from_model(file), - ) - .await?; - - Ok(()) + ctx.response(FileBasicDataResponse::from_model(file)) } #[tracing::instrument(skip_all)] - async fn update_status(ctx: &Context, event: Event) -> IPCResult<()> { + async fn update_status(ctx: &Context, event: Event) -> IPCResult { let request = event.payload::()?; let repo = get_repo_from_context(ctx).await; let mut file = file_by_identifier(request.file_id, &repo).await?; @@ -207,46 +189,35 @@ impl FilesNamespace { ..Default::default() }) .await?; - ctx.emit_to( - Self::name(), - "update_file_status", - FileBasicDataResponse::from_model(file), - ) - .await?; - - Ok(()) + + ctx.response(FileBasicDataResponse::from_model(file)) } /// Reads the binary contents of a file #[tracing::instrument(skip_all)] - async fn read_file(ctx: &Context, event: Event) -> IPCResult<()> { + async fn read_file(ctx: &Context, event: Event) -> IPCResult { let request = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file = file_by_identifier(request.id, &repo).await?; let bytes = repo.file().get_bytes(file.cd()).await?; - ctx.emit_to(Self::name(), "read_file", BytePayload::new(bytes)) - .await?; - - Ok(()) + ctx.response(BytePayload::new(bytes)) } /// Deletes a file #[tracing::instrument(skip_all)] - async fn delete_file(ctx: &Context, event: Event) -> IPCResult<()> { + async fn delete_file(ctx: &Context, event: Event) -> IPCResult { let id = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file = file_by_identifier(id, &repo).await?; repo.file().delete(file).await?; - ctx.emit_to(Self::name(), "delete_file", ()).await?; - - Ok(()) + Ok(Response::empty()) } /// Returns a list of available thumbnails of a file #[tracing::instrument(skip_all)] - async fn thumbnails(ctx: &Context, event: Event) -> IPCResult<()> { + async fn thumbnails(ctx: &Context, event: Event) -> IPCResult { let request = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file_cd = cd_by_identifier(request.id.clone(), &repo).await?; @@ -260,7 +231,7 @@ impl FilesNamespace { let file = file_by_identifier(request.id, &repo).await?; thumbnails = repo .file() - .create_thumbnails(file, vec![ThumbnailSize::Medium]) + .create_thumbnails(&file, vec![ThumbnailSize::Medium]) .await?; tracing::debug!("Thumbnails for file created."); } @@ -269,15 +240,13 @@ impl FilesNamespace { .into_iter() .map(ThumbnailMetadataResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "get_thumbnails", thumb_responses) - .await?; - Ok(()) + ctx.response(thumb_responses) } /// Returns a thumbnail that is within the range of the requested sizes #[tracing::instrument(skip_all)] - async fn get_thumbnail_of_size(ctx: &Context, event: Event) -> IPCResult<()> { + async fn get_thumbnail_of_size(ctx: &Context, event: Event) -> IPCResult { let request = event.payload::()?; let repo = get_repo_from_context(ctx).await; let file_cd = cd_by_identifier(request.id.clone(), &repo).await?; @@ -302,7 +271,7 @@ impl FilesNamespace { let middle_size = ((max_size.0 + min_size.0) / 2, (max_size.1 + min_size.1) / 2); let thumbnail = repo .file() - .create_thumbnails(file, vec![ThumbnailSize::Custom(middle_size)]) + .create_thumbnails(&file, vec![ThumbnailSize::Custom(middle_size)]) .await?; thumbnail @@ -314,19 +283,13 @@ impl FilesNamespace { thumbnail.get_reader().await?.read_to_end(&mut buf).await?; let byte_payload = BytePayload::new(buf); let thumb_payload = ThumbnailMetadataResponse::from_model(thumbnail); - ctx.emit_to( - Self::name(), - "get_thumbnail_of_size", - TandemPayload::new(thumb_payload, byte_payload), - ) - .await?; - - Ok(()) + + ctx.response(TandemPayload::new(thumb_payload, byte_payload)) } /// Updates the name of a file #[tracing::instrument(skip_all)] - async fn update_file_name(ctx: &Context, event: Event) -> IPCResult<()> { + async fn update_file_name(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let request = event.payload::()?; let file = file_by_identifier(request.file_id, &repo).await?; @@ -340,19 +303,12 @@ impl FilesNamespace { }) .await?; - ctx.emit_to( - Self::name(), - "update_file_name", - FileMetadataResponse::from_model(metadata), - ) - .await?; - - Ok(()) + ctx.response(FileMetadataResponse::from_model(metadata)) } /// Deletes all thumbnails of a file #[tracing::instrument(skip_all)] - async fn delete_thumbnails(ctx: &Context, event: Event) -> IPCResult<()> { + async fn delete_thumbnails(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let id = event.payload::()?; let file = file_by_identifier(id, &repo).await?; @@ -362,6 +318,6 @@ impl FilesNamespace { thumb.delete().await?; } - Ok(()) + Ok(Response::empty()) } } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs index 52e1ef4..c912b70 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs @@ -23,20 +23,24 @@ impl NamespaceProvider for JobsNamespace { impl JobsNamespace { #[tracing::instrument(skip_all)] - pub async fn run_job(ctx: &Context, event: Event) -> IPCResult<()> { + pub async fn run_job(ctx: &Context, event: Event) -> IPCResult { let run_request = event.payload::()?; let job_dao = get_repo_from_context(ctx).await.job(); + if !run_request.sync { + // early response to indicate that the job will be run + ctx.emit_to(Self::name(), "run_job", ()).await?; + } + match run_request.job_type { JobType::MigrateContentDescriptors => job_dao.migrate_content_descriptors().await?, JobType::CalculateSizes => calculate_all_sizes(ctx).await?, JobType::CheckIntegrity => job_dao.check_integrity().await?, JobType::Vacuum => job_dao.vacuum().await?, + JobType::GenerateThumbnails => job_dao.generate_missing_thumbnails().await?, } - ctx.emit_to(Self::name(), "run_job", ()).await?; - - Ok(()) + Ok(Response::empty()) } } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs index fbcd50c..91f4ac8 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/presets.rs @@ -23,7 +23,7 @@ impl NamespaceProvider for PresetsNamespace { impl PresetsNamespace { #[tracing::instrument(skip_all)] - pub async fn all_sorting_presets(ctx: &Context, _: Event) -> IPCResult<()> { + pub async fn all_sorting_presets(ctx: &Context, _: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let sorting_presets: Vec = repo .sorting_preset() @@ -32,14 +32,12 @@ impl PresetsNamespace { .into_iter() .map(SortingPreset::from_model) .collect(); - ctx.emit_to(Self::name(), "all_sorting_presets", sorting_presets) - .await?; - Ok(()) + ctx.response(sorting_presets) } #[tracing::instrument(skip_all)] - pub async fn add_sorting_preset(ctx: &Context, event: Event) -> IPCResult<()> { + pub async fn add_sorting_preset(ctx: &Context, event: Event) -> IPCResult { let keys = event .payload::>()? .into_iter() @@ -50,25 +48,17 @@ impl PresetsNamespace { .sorting_preset() .add(AddSortingPresetDto { keys }) .await?; - ctx.emit_to( - Self::name(), - "add_sorting_preset", - SortingPreset::from_model(preset), - ) - .await?; - Ok(()) + ctx.response(SortingPreset::from_model(preset)) } #[tracing::instrument(skip_all)] - pub async fn delete_sorting_preset(ctx: &Context, event: Event) -> IPCResult<()> { + pub async fn delete_sorting_preset(ctx: &Context, event: Event) -> IPCResult { let id = event.payload::()?; let repo = get_repo_from_context(ctx).await; repo.sorting_preset().delete(id).await?; - ctx.emit_to(Self::name(), "delete_sorting_preset", ()) - .await?; - Ok(()) + Ok(Response::empty()) } } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/repo.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/repo.rs index 7f3aa5a..953f0a3 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/repo.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/repo.rs @@ -29,7 +29,7 @@ impl NamespaceProvider for RepoNamespace { impl RepoNamespace { #[tracing::instrument(skip_all)] - async fn get_metadata(ctx: &Context, _: Event) -> IPCResult<()> { + async fn get_metadata(ctx: &Context, _: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let counts = repo.get_counts().await?; @@ -43,14 +43,12 @@ impl RepoNamespace { }; tracing::debug!("metadata = {:?}", metadata); - ctx.emit_to(Self::name(), "repository_metadata", metadata) - .await?; - Ok(()) + ctx.response(metadata) } #[tracing::instrument(skip_all)] - async fn get_size_metadata(ctx: &Context, event: Event) -> IPCResult<()> { + async fn get_size_metadata(ctx: &Context, event: Event) -> IPCResult { let size_type = event.payload::()?; let data = ctx.data.read().await; let size_cache = data.get::().unwrap(); @@ -61,38 +59,25 @@ impl RepoNamespace { calculate_size(&size_type, ctx).await? }; - ctx.emit_to( - Self::name(), - "size_metadata", - SizeMetadata { size, size_type }, - ) - .await?; - - Ok(()) + ctx.response(SizeMetadata { size, size_type }) } #[tracing::instrument(skip_all)] - async fn frontend_state(ctx: &Context, _: Event) -> IPCResult<()> { + async fn frontend_state(ctx: &Context, _: Event) -> IPCResult { let path = get_frontend_state_path(ctx).await?; let state_string = if path.exists() { Some(fs::read_to_string(path).await?) } else { None }; - ctx.emit_to( - Self::name(), - "frontend_state", - FrontendState { - state: state_string, - }, - ) - .await?; - - Ok(()) + + ctx.response(FrontendState { + state: state_string, + }) } #[tracing::instrument(skip_all)] - async fn set_frontend_state(ctx: &Context, event: Event) -> IPCResult<()> { + async fn set_frontend_state(ctx: &Context, event: Event) -> IPCResult { let path = get_frontend_state_path(ctx).await?; let state = event.payload::()?.state; if let Some(state_string) = state { @@ -101,7 +86,7 @@ impl RepoNamespace { fs::remove_file(path).await?; } - Ok(()) + Ok(Response::empty()) } } diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs index ef6543b..b3fa43a 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/tags.rs @@ -39,7 +39,7 @@ impl NamespaceProvider for TagsNamespace { impl TagsNamespace { /// Returns a list of all tags in the database #[tracing::instrument(skip_all)] - async fn all_tags(ctx: &Context, _event: Event) -> IPCResult<()> { + async fn all_tags(ctx: &Context, _event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let tags: Vec = repo .tag() @@ -48,14 +48,13 @@ impl TagsNamespace { .into_iter() .map(TagResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "all_tags", tags).await?; - Ok(()) + ctx.response(tags) } /// Returns a list of all namespaces from the database #[tracing::instrument(skip_all)] - async fn all_namespaces(ctx: &Context, _event: Event) -> IPCResult<()> { + async fn all_namespaces(ctx: &Context, _event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let namespaces: Vec = repo .tag() @@ -64,30 +63,25 @@ impl TagsNamespace { .into_iter() .map(NamespaceResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "all_namespaces", namespaces) - .await?; - Ok(()) + ctx.response(namespaces) } /// Returns all tags for a single file #[tracing::instrument(skip_all)] - async fn tags_for_file(ctx: &Context, event: Event) -> IPCResult<()> { + async fn tags_for_file(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let request = event.payload::()?; let file = file_by_identifier(request.id, &repo).await?; let tags = repo.tag().tags_for_cd(file.cd_id()).await?; let responses: Vec = tags.into_iter().map(TagResponse::from_model).collect(); - ctx.emit_to(Self::name(), "tags_for_file", responses) - .await?; - - Ok(()) + ctx.response(responses) } /// Returns all tags for a given list of file hashes #[tracing::instrument(skip_all)] - async fn tags_for_files(ctx: &Context, event: Event) -> IPCResult<()> { + async fn tags_for_files(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let request = event.payload::()?; let tag_responses: Vec = repo @@ -103,15 +97,13 @@ impl TagsNamespace { .into_iter() .map(TagResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "tags_for_files", tag_responses) - .await?; - Ok(()) + ctx.response(tag_responses) } /// Returns a map of content descriptors to assigned tags #[tracing::instrument(skip_all)] - async fn tag_cd_map_for_files(ctx: &Context, event: Event) -> IPCResult<()> { + async fn tag_cd_map_for_files(ctx: &Context, event: Event) -> IPCResult { let request = event.payload::()?; let repo = get_repo_from_context(ctx).await; let cds = request @@ -136,14 +128,12 @@ impl TagsNamespace { }) .collect::>>(); - ctx.emit_to(Self::name(), "file_tag_map", mappings).await?; - - Ok(()) + ctx.response(mappings) } /// Creates all tags given as input or returns the existing tags #[tracing::instrument(skip_all)] - async fn create_tags(ctx: &Context, event: Event) -> IPCResult<()> { + async fn create_tags(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let tags = event.payload::>()?; let created_tags = repo @@ -160,15 +150,14 @@ impl TagsNamespace { .into_iter() .map(TagResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "create_tags", responses).await?; - Ok(()) + ctx.response(responses) } /// Changes tags of a file /// it removes the tags from the removed list and adds the one from the add list #[tracing::instrument(skip_all)] - async fn change_file_tags(ctx: &Context, event: Event) -> IPCResult<()> { + async fn change_file_tags(ctx: &Context, event: Event) -> IPCResult { let repo = get_repo_from_context(ctx).await; let request = event.payload::()?; let file = file_by_identifier(request.file_id, &repo).await?; @@ -191,9 +180,7 @@ impl TagsNamespace { .into_iter() .map(TagResponse::from_model) .collect(); - ctx.emit_to(Self::name(), "change_file_tags", responses) - .await?; - Ok(()) + ctx.response(responses) } } diff --git a/mediarepo-daemon/src/main.rs b/mediarepo-daemon/src/main.rs index 757dffe..55f608d 100644 --- a/mediarepo-daemon/src/main.rs +++ b/mediarepo-daemon/src/main.rs @@ -55,7 +55,14 @@ fn main() -> RepoResult<()> { let settings = if opt.repo.exists() { opt.repo = opt.repo.canonicalize().unwrap(); - load_settings(&opt.repo)? + + match load_settings(&opt.repo) { + Ok(s) => s, + Err(e) => { + log::warn!("failed to read settings {}", e); + Settings::default() + } + } } else { Settings::default() }; diff --git a/mediarepo-ui/.browserslistrc b/mediarepo-ui/.browserslistrc index 427441d..c289ba6 100644 --- a/mediarepo-ui/.browserslistrc +++ b/mediarepo-ui/.browserslistrc @@ -11,7 +11,6 @@ last 1 Chrome version last 1 Firefox version last 2 Edge major versions -last 2 Safari major versions last 2 iOS major versions Firefox ESR not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/mediarepo-ui/angular.json b/mediarepo-ui/angular.json index 74ad062..ce505ab 100644 --- a/mediarepo-ui/angular.json +++ b/mediarepo-ui/angular.json @@ -37,7 +37,8 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/purple-green.css", - "src/styles.scss" + "src/styles.scss", + "src/material-theme-correction.scss" ], "scripts": [] }, @@ -46,13 +47,13 @@ "budgets": [ { "type": "initial", - "maximumWarning": "1mb", - "maximumError": "10mb" + "maximumWarning": "20mb", + "maximumError": "400mb" }, { "type": "anyComponentStyle", - "maximumWarning": "6kb", - "maximumError": "100kb" + "maximumWarning": "100kb", + "maximumError": "500kb" } ], "fileReplacements": [ @@ -110,7 +111,8 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/purple-green.css", - "src/styles.scss" + "src/styles.scss", + "src/material-theme-correction.scss" ], "scripts": [] } diff --git a/mediarepo-ui/package.json b/mediarepo-ui/package.json index 15e81d7..1ec24c4 100644 --- a/mediarepo-ui/package.json +++ b/mediarepo-ui/package.json @@ -1,6 +1,6 @@ { "name": "mediarepo-ui", - "version": "0.13.4", + "version": "1.0.0-rc.1", "scripts": { "ng": "ng", "start": "ng serve", diff --git a/mediarepo-ui/src-tauri/Cargo.lock b/mediarepo-ui/src-tauri/Cargo.lock index 88c9b74..40b6e09 100644 --- a/mediarepo-ui/src-tauri/Cargo.lock +++ b/mediarepo-ui/src-tauri/Cargo.lock @@ -40,7 +40,7 @@ checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "app" -version = "0.13.4" +version = "1.0.0-rc.1" dependencies = [ "mediarepo-api", "serde", @@ -170,15 +170,16 @@ dependencies = [ [[package]] name = "bromine" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6774171be092328d9631f246d3122f196a50ddaad224214ca274acec2a1db65d" +checksum = "5dd7887995490657bf3ec578f39e747ef7b5355a8dc6c99b3d5be59ca70dc4d5" dependencies = [ "async-trait", "bincode", "byteorder", - "futures", + "futures-core", "lazy_static", + "num_enum", "serde", "thiserror", "tokio", @@ -809,9 +810,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -824,9 +825,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -834,15 +835,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -851,9 +852,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-lite" @@ -872,9 +873,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2 1.0.36", "quote 1.0.15", @@ -883,21 +884,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -1499,7 +1500,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mediarepo-api" -version = "0.28.1" +version = "0.31.0" dependencies = [ "async-trait", "bromine", @@ -1875,7 +1876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.0", + "parking_lot_core 0.9.1", ] [[package]] @@ -1894,9 +1895,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f4f894f3865f6c0e02810fc597300f34dc2510f66400da262d8ae10e75767d" +checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" dependencies = [ "cfg-if 1.0.0", "libc", @@ -3097,9 +3098,21 @@ dependencies = [ "once_cell", "pin-project-lite", "signal-hook-registry", + "tokio-macros", "winapi", ] +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2 1.0.36", + "quote 1.0.15", + "syn 1.0.86", +] + [[package]] name = "toml" version = "0.5.8" @@ -3508,9 +3521,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceb069ac8b2117d36924190469735767f0990833935ab430155e71a44bafe148" +checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -3521,33 +3534,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b" +checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" [[package]] name = "windows_i686_gnu" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58" +checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" [[package]] name = "windows_i686_msvc" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4" +checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" [[package]] name = "windows_x86_64_gnu" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354" +checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" [[package]] name = "windows_x86_64_msvc" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561" +checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" [[package]] name = "winres" diff --git a/mediarepo-ui/src-tauri/Cargo.toml b/mediarepo-ui/src-tauri/Cargo.toml index 4447a46..c794d70 100644 --- a/mediarepo-ui/src-tauri/Cargo.toml +++ b/mediarepo-ui/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "app" -version = "0.13.4" +version = "1.0.0-rc.1" description = "The UI for the mediarepo media management tool" authors = ["you"] license = "" diff --git a/mediarepo-ui/src-tauri/src/main.rs b/mediarepo-ui/src-tauri/src/main.rs index 0502136..c35fe60 100644 --- a/mediarepo-ui/src-tauri/src/main.rs +++ b/mediarepo-ui/src-tauri/src/main.rs @@ -1,19 +1,24 @@ #![cfg_attr( - all(not(debug_assertions), target_os = "windows"), - windows_subsystem = "windows" +all(not(debug_assertions), target_os = "windows"), +windows_subsystem = "windows" )] -use tracing_subscriber::fmt::format::FmtSpan; +use tauri::{LogicalSize, Size}; use tracing_subscriber::EnvFilter; +use tracing_subscriber::fmt::format::FmtSpan; fn main() { - tracing_subscriber::fmt::SubscriberBuilder::default() - .with_env_filter(EnvFilter::from_default_env()) - .with_writer(std::io::stdout) - .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) - .compact() - .init(); - mediarepo_api::tauri_plugin::register_plugin(tauri::Builder::default()) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + tracing_subscriber::fmt::SubscriberBuilder::default() + .with_env_filter(EnvFilter::from_default_env()) + .with_writer(std::io::stdout) + .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) + .compact() + .init(); + mediarepo_api::tauri_plugin::register_plugin(tauri::Builder::default()) + .on_page_load(|window, _| { + window.set_title(format!("mediarepo {}", env!("CARGO_PKG_VERSION")).as_str()).expect("failed to set window title"); + window.set_min_size(Some(Size::Logical(LogicalSize { width: 1000.0, height: 750.0 }))).expect("failed to set minimal size"); + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); } diff --git a/mediarepo-ui/src-tauri/tauri.conf.json b/mediarepo-ui/src-tauri/tauri.conf.json index 55ea445..94e187d 100644 --- a/mediarepo-ui/src-tauri/tauri.conf.json +++ b/mediarepo-ui/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "mediarepo-ui", - "version": "0.13.4" + "version": "1.0.0-rc.1" }, "build": { "distDir": "../dist/mediarepo-ui", diff --git a/mediarepo-ui/src/api/api-types/files.ts b/mediarepo-ui/src/api/api-types/files.ts index cf6387d..f40d1bb 100644 --- a/mediarepo-ui/src/api/api-types/files.ts +++ b/mediarepo-ui/src/api/api-types/files.ts @@ -68,9 +68,10 @@ export type FileMetadata = { file_id: number, name?: string, comment?: string, - creation_time: Date, - change_time: Date, - import_time: Date, + creation_time: string, + change_time: string, + import_time: string, + size: number, }; export type FileOsMetadata = { diff --git a/mediarepo-ui/src/api/api-types/job.ts b/mediarepo-ui/src/api/api-types/job.ts index cda973f..8edff1d 100644 --- a/mediarepo-ui/src/api/api-types/job.ts +++ b/mediarepo-ui/src/api/api-types/job.ts @@ -1,4 +1,5 @@ export type JobType = "MigrateContentDescriptors" | "CalculateSizes" | "CheckIntegrity" - | "Vacuum"; + | "Vacuum" + | "GenerateThumbnails"; diff --git a/mediarepo-ui/src/api/api-types/requests.ts b/mediarepo-ui/src/api/api-types/requests.ts index f0bec62..2a813b6 100644 --- a/mediarepo-ui/src/api/api-types/requests.ts +++ b/mediarepo-ui/src/api/api-types/requests.ts @@ -107,6 +107,7 @@ export type SetFrontendStateRequest = { export type RunJobRequest = { jobType: JobType, + sync: boolean, }; export type AddSortingPresetRequest = { diff --git a/mediarepo-ui/src/api/models/FilterQueryBuilder.ts b/mediarepo-ui/src/api/models/FilterQueryBuilder.ts index 48c1a1f..95e7827 100644 --- a/mediarepo-ui/src/api/models/FilterQueryBuilder.ts +++ b/mediarepo-ui/src/api/models/FilterQueryBuilder.ts @@ -1,4 +1,5 @@ import {FileStatus, FilterExpression, FilterQuery, PropertyQuery, ValueComparator} from "../api-types/files"; +import {normalizeTag} from "../../app/utils/tag-utils"; export type Comparator = "Less" | "Equal" | "Greater" | "Between"; export type PropertyType = @@ -14,7 +15,7 @@ export type PropertyType = export class FilterQueryBuilder { public static tag(tag: string, negate: boolean): FilterQuery { - return { Tag: { tag, negate } }; + return { Tag: { tag: normalizeTag(tag), negate } }; } public static status(status: FileStatus): FilterQuery { @@ -74,7 +75,7 @@ export class FilterQueryBuilder { } public static buildFilterFromString(filterStr: string): FilterQuery | undefined { - filterStr = filterStr.trim(); + filterStr = filterStr.trim().toLowerCase(); if (filterStr.startsWith(".")) { const cleanFilter = filterStr.replace(/^\./, ""); diff --git a/mediarepo-ui/src/app/app.component-theme.scss b/mediarepo-ui/src/app/app.component-theme.scss deleted file mode 100644 index e43e010..0000000 --- a/mediarepo-ui/src/app/app.component-theme.scss +++ /dev/null @@ -1,40 +0,0 @@ -@use 'sass:map'; -@use '@angular/material' as mat; - -@mixin color($theme) { - $color-config: mat.get-color-config($theme); - $primary-palette: map.get($color-config, 'primary'); - $warn-palette: map.get($color-config, 'warn'); - - body { - background-color: darken(#303030, 5); - color: white - } - - .warn { - background-color: mat.get-color-from-palette($warn-palette); - color: white - } -} - -@mixin typography($theme) { - // Get the typography config from the theme. - $typography-config: mat.get-typography-config($theme); - - body { - font-family: mat.font-family($typography-config); - } -} - -@mixin theme($theme) { - $color-config: mat.get-color-config($theme); - @if $color-config != null { - @include color($theme); - } - - $typography-config: mat.get-typography-config($theme); - @if $typography-config != null { - @include typography($theme); - } -} - diff --git a/mediarepo-ui/src/app/app.component.scss b/mediarepo-ui/src/app/app.component.scss index bfa0fc0..5218a02 100644 --- a/mediarepo-ui/src/app/app.component.scss +++ b/mediarepo-ui/src/app/app.component.scss @@ -1,5 +1,16 @@ @import "src/colors"; +:host, ::ng-deep body { + font-family: $font-family; + background-color: $background; + color: white +} + +::ng-deep .warn { + background-color: $warn; + color: white +} + ::ng-deep .mat-button-wrapper > ng-icon { font-size: 26px; } @@ -16,3 +27,4 @@ background-color: $warn; color: $text; } + diff --git a/mediarepo-ui/src/app/components/core/core.component.html b/mediarepo-ui/src/app/components/core/core.component.html index f2a5fea..def7489 100644 --- a/mediarepo-ui/src/app/components/core/core.component.html +++ b/mediarepo-ui/src/app/components/core/core.component.html @@ -14,20 +14,16 @@ - - + + -
- Select the tab type - - -
+
- diff --git a/mediarepo-ui/src/app/components/core/core.component.ts b/mediarepo-ui/src/app/components/core/core.component.ts index 6b07685..edf3026 100644 --- a/mediarepo-ui/src/app/components/core/core.component.ts +++ b/mediarepo-ui/src/app/components/core/core.component.ts @@ -4,10 +4,10 @@ import {RepositoryService} from "../../services/repository/repository.service"; import {MatTabChangeEvent, MatTabGroup} from "@angular/material/tabs"; import {TagService} from "../../services/tag/tag.service"; import {TabService} from "../../services/tab/tab.service"; -import {TabCategory} from "../../models/TabCategory"; -import {TabState} from "../../models/TabState"; -import {AppState} from "../../models/AppState"; +import {TabCategory} from "../../models/state/TabCategory"; +import {AppState} from "../../models/state/AppState"; import {StateService} from "../../services/state/state.service"; +import {TabState} from "../../models/state/TabState"; @Component({ selector: "app-core", @@ -45,7 +45,7 @@ export class CoreComponent { this.stateService.state.subscribe(state => { this.appState = state; if (this.appState.tabs.value.length === 0) { - this.addTab(); + this.addEmptyTab(); } else { this.tabGroup.selectedIndex = 1; } @@ -58,7 +58,7 @@ export class CoreComponent { } if (this.tabs.length === 0) { - this.addTab(); + this.addEmptyTab(); } }); }); @@ -76,19 +76,7 @@ export class CoreComponent { } } - public addFilesTab(): void { - this.appState.addTab(TabCategory.Files); - this.tabGroup.selectedIndex = this.tabs.length; - this.newTab = false; - } - - public addImportTab(): void { - this.appState.addTab(TabCategory.Import); - this.tabGroup.selectedIndex = this.tabs.length; - this.newTab = false; - } - - public addTab(): void { + public addEmptyTab(): void { if (this.tabGroup) { this.newTab = true; this.tabGroup.selectedIndex = this.tabs.length + 1; @@ -119,4 +107,10 @@ export class CoreComponent { public trackByTabId(index: number, item: TabState) { return item.uuid; } + + public addTab(category: TabCategory): void { + this.appState.addTab(category); + this.tabGroup.selectedIndex = this.tabs.length; + this.newTab = false; + } } diff --git a/mediarepo-ui/src/app/components/core/core.module.ts b/mediarepo-ui/src/app/components/core/core.module.ts index dbd097f..a514aba 100644 --- a/mediarepo-ui/src/app/components/core/core.module.ts +++ b/mediarepo-ui/src/app/components/core/core.module.ts @@ -39,6 +39,7 @@ import {MatToolbarModule} from "@angular/material/toolbar"; import { RepositoryDetailsViewComponent } from "./repositories-tab/repository-details-view/repository-details-view.component"; +import { EmptyTabComponent } from './empty-tab/empty-tab.component'; @NgModule({ @@ -52,6 +53,7 @@ import { RepositoryCardComponent, DownloadDaemonDialogComponent, RepositoryDetailsViewComponent, + EmptyTabComponent, ], exports: [ CoreComponent, diff --git a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.html b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.html new file mode 100644 index 0000000..4e8bfa9 --- /dev/null +++ b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.html @@ -0,0 +1,7 @@ + +

What kind of tab do you want to open?

+
+ + +
+
diff --git a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.scss b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.scss new file mode 100644 index 0000000..611f3ae --- /dev/null +++ b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.scss @@ -0,0 +1,31 @@ +@import "src/colors"; + +:host { + height: 100%; + width: 100%; + display: block; + background: radial-gradient(circle, $background-darker-05 80%, $primary 200%); +} + +.button-container { + height: 6em; + display: block; + width: 100%; + position: relative; +} + +button { + padding: 0.5em 1em; + font-size: 1.5em; + margin: 1em; + border-radius: 0.5em; + transition-duration: 0.25s; + + &:hover { + scale: 1.25; + } + + &:active { + scale: 1; + } +} diff --git a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.spec.ts b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.spec.ts new file mode 100644 index 0000000..482992e --- /dev/null +++ b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {EmptyTabComponent} from "./empty-tab.component"; + +describe("EmptyTabComponent", () => { + let component: EmptyTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [EmptyTabComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EmptyTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts new file mode 100644 index 0000000..fd9fa5f --- /dev/null +++ b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts @@ -0,0 +1,29 @@ +import {ChangeDetectionStrategy, Component, EventEmitter, Output} from "@angular/core"; +import {TabCategory} from "../../../models/state/TabCategory"; + +type TabCategoryName = "files" | "import"; + +@Component({ + selector: "app-empty-tab", + templateUrl: "./empty-tab.component.html", + styleUrls: ["./empty-tab.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class EmptyTabComponent { + + @Output() tabCategorySelect = new EventEmitter(); + + constructor() { + } + + public addTab(category: TabCategoryName) { + switch (category) { + case "files": + this.tabCategorySelect.emit(TabCategory.Files); + break; + case "import": + this.tabCategorySelect.emit(TabCategory.Import); + break; + } + } +} diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts b/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts index 311bce8..e9d3d5f 100644 --- a/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts +++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts @@ -5,7 +5,7 @@ import {File} from "../../../../../api/models/File"; import {FileSearchComponent} from "../../../shared/sidebar/file-search/file-search.component"; import {RepositoryService} from "../../../../services/repository/repository.service"; import {TagEditComponent} from "../../../shared/sidebar/tag-edit/tag-edit.component"; -import {TabState} from "../../../../models/TabState"; +import {FilesTabState} from "../../../../models/state/FilesTabState"; @Component({ selector: "app-files-tab-sidebar", @@ -14,7 +14,7 @@ import {TabState} from "../../../../models/TabState"; }) export class FilesTabSidebarComponent implements OnInit, OnChanges { - @Input() state!: TabState; + @Input() state!: FilesTabState; @Input() selectedFiles: File[] = []; @Output() searchStartEvent = new EventEmitter(); @Output() searchEndEvent = new EventEmitter(); diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.html b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.html index c871514..2a76623 100644 --- a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.html +++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.html @@ -1,12 +1,15 @@ - - + + - - - + + + - - + +

There are no files in this repository.

+ +
+ + diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.scss b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.scss index d422cb8..e3939bf 100644 --- a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.scss +++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.scss @@ -2,24 +2,6 @@ mat-selection-list { height: 100%; } -mat-drawer { - height: 100%; - width: 25%; - overflow: hidden; -} - -mat-drawer-content { - overflow-x: hidden; - overflow-y: auto; - height: 100%; -} - -mat-drawer-container { - height: 100%; - width: 100%; - overflow: hidden; -} - app-file-multiview { padding: 0; height: 100%; @@ -43,3 +25,11 @@ app-file-multiview { margin: auto; } } + +.import-prompt { + button { + font-size: 1.5em; + padding: 0.5em 1em; + border-radius: 0.5em; + } +} diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts index 7a588f3..8233c6c 100644 --- a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts +++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts @@ -1,6 +1,9 @@ import {Component, Input, OnInit} from "@angular/core"; import {File} from "../../../../api/models/File"; -import {TabState} from "../../../models/TabState"; +import {FilesTabState} from "../../../models/state/FilesTabState"; +import {RepositoryMetadata} from "../../../../api/api-types/repo"; +import {RepositoryService} from "../../../services/repository/repository.service"; +import {TabCategory} from "../../../models/state/TabCategory"; @Component({ selector: "app-files-tab", @@ -9,13 +12,17 @@ import {TabState} from "../../../models/TabState"; }) export class FilesTabComponent implements OnInit { - @Input() state!: TabState; + @Input() state!: FilesTabState; files: File[] = []; contentLoading = false; selectedFiles: File[] = []; + public metadata?: RepositoryMetadata; - constructor() { + constructor( + repoService: RepositoryService, + ) { + repoService.metadata.subscribe(m => this.metadata = m); } async ngOnInit() { @@ -50,4 +57,8 @@ export class FilesTabComponent implements OnInit { break; } } + + public onImportFiles(): void { + this.state.category = TabCategory.Import; + } } diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.html b/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.html index 8d5025a..1e8e1c8 100644 --- a/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.html +++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.html @@ -1,8 +1,8 @@
- + diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.ts b/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.ts index a9b6b32..5b07abe 100644 --- a/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.ts +++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab-sidebar/import-tab-sidebar.component.ts @@ -1,13 +1,16 @@ -import {Component, EventEmitter, Input, Output} from "@angular/core"; +import {ChangeDetectionStrategy, Component, EventEmitter, Input, Output} from "@angular/core"; import {File} from "../../../../../api/models/File"; +import {ImportTabState} from "../../../../models/state/ImportTabState"; @Component({ selector: "app-import-tab-sidebar", templateUrl: "./import-tab-sidebar.component.html", - styleUrls: ["./import-tab-sidebar.component.scss"] + styleUrls: ["./import-tab-sidebar.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush }) export class ImportTabSidebarComponent { + @Input() state!: ImportTabState; @Input() selectedFiles: File[] = []; @Output() fileImported = new EventEmitter(); @Output() importFinished = new EventEmitter(); diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.html b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.html index 7b29bbf..bd12781 100644 --- a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.html +++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.html @@ -1,14 +1,14 @@ - - - - - + + + + + - - + + diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.scss b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.scss index 009d9c8..1fbab13 100644 --- a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.scss +++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.scss @@ -1,21 +1,3 @@ -mat-drawer-container { - height: 100%; - width: 100%; - margin: 0; - overflow: hidden; -} - -mat-drawer-content { - overflow-x: hidden; - overflow-y: auto; - height: 100%; -} - -mat-drawer { - height: 100%; - width: 25%; -} - app-import-tab-sidebar, app-file-multiview { height: 100%; width: 100%; diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts index c89512a..9c691ab 100644 --- a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts +++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts @@ -1,48 +1,27 @@ -import {Component, Input, OnInit} from "@angular/core"; +import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit} from "@angular/core"; import {File} from "../../../../api/models/File"; -import {TabState} from "../../../models/TabState"; +import {ImportTabState} from "../../../models/state/ImportTabState"; @Component({ selector: "app-import-tab", templateUrl: "./import-tab.component.html", - styleUrls: ["./import-tab.component.scss"] + styleUrls: ["./import-tab.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush }) export class ImportTabComponent implements OnInit { - @Input() state!: TabState; + @Input() state!: ImportTabState; public files: File[] = []; public selectedFiles: File[] = []; - private newFiles: File[] = []; - - constructor() { + constructor(private changeDetector: ChangeDetectorRef) { } public ngOnInit(): void { this.state.files.subscribe(files => files ? this.files = files : undefined); } - /** - * Adds an imported file to the list of imported files - * @param {File} file - * @returns {Promise} - */ - public async addFileFromImport(file: File) { - this.newFiles.push(file); - if (this.newFiles.length % 50 === 0) { // refresh every 50 pictures - this.refreshFileView(); - } - } - - /** - * Refreshes the file view - * @returns {Promise} - */ - public refreshFileView() { - this.state.files.next([...this.state.files.value, ...this.newFiles]); - this.newFiles = []; - } public onFileSelect(files: File[]) { this.selectedFiles = files; diff --git a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.html b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.html index 90c40cd..48622cd 100644 --- a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.html +++ b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.html @@ -7,6 +7,10 @@
+ +

There are no repositories yet. You can create a repository or add an existing one.

+ +
diff --git a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.scss b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.scss index 3c0880f..4e2ab92 100644 --- a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.scss +++ b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.scss @@ -31,3 +31,11 @@ app-repository-card { app-repository-details-view, .repo-details { height: 100%; } + +.add-repository-prompt { + button { + font-size: 1.5em; + padding: 0.5em 1em; + border-radius: 0.5em; + } +} diff --git a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts index ecb4843..3c4f421 100644 --- a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts +++ b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts @@ -119,7 +119,9 @@ export class RepositoriesTabComponent implements OnInit, AfterViewInit { "Migrating content descriptors to new format..."); await this.jobService.runJob("MigrateContentDescriptors"); dialogContext.message.next("Calculating repository sizes..."); - await this.jobService.runJob("CalculateSizes"); + await this.jobService.runJob("CalculateSizes", false); + dialogContext.message.next("Generating missing thumbnails..."); + await this.jobService.runJob("GenerateThumbnails"); dialogContext.message.next("Finished repository startup"); } @@ -128,7 +130,7 @@ export class RepositoriesTabComponent implements OnInit, AfterViewInit { "Opening repository..."); let dialog = this.dialog.open(BusyDialogComponent, { data: { - title: `Opening repository ${repository.name}`, + title: `Opening repository '${repository.name}'`, message: dialogMessage, allowCancel: true, }, disableClose: true, diff --git a/mediarepo-ui/src/app/components/shared/app-common/app-common.module.ts b/mediarepo-ui/src/app/components/shared/app-common/app-common.module.ts index abdf5e2..a556c14 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/app-common.module.ts +++ b/mediarepo-ui/src/app/components/shared/app-common/app-common.module.ts @@ -4,6 +4,7 @@ import {BusyIndicatorComponent} from "./busy-indicator/busy-indicator.component" import {ContextMenuComponent} from "./context-menu/context-menu.component"; import {CommonModule} from "@angular/common"; import {NgIconsModule} from "@ng-icons/core"; +import {MatChevronLeft, MatChevronRight} from "@ng-icons/material-icons"; import {MatProgressSpinnerModule} from "@angular/material/progress-spinner"; import {MatButtonModule} from "@angular/material/button"; import {MatDialogModule} from "@angular/material/dialog"; @@ -15,6 +16,15 @@ import {BusyDialogComponent} from "./busy-dialog/busy-dialog.component"; import {SelectableComponent} from "./selectable/selectable.component"; import {MatProgressBarModule} from "@angular/material/progress-bar"; import {HasPropertyPipe} from "./pipes/has-property.pipe"; +import {DrawerPageComponent} from "./drawer-page/drawer-page.component"; +import {MatSidenavModule} from "@angular/material/sidenav"; +import {DrawerPageSideComponent} from "./drawer-page/drawer-page-side/drawer-page-side.component"; +import {DrawerPageContentComponent} from "./drawer-page/drawer-page-content/drawer-page-content.component"; +import {FlexLayoutModule} from "@angular/flex-layout"; +import {MatRippleModule} from "@angular/material/core"; +import {FlapButtonComponent} from "./flap-button/flap-button.component"; +import {MiddleCenteredComponent} from "./middle-centered/middle-centered.component"; +import {FormatBytesPipe} from "./pipes/format-bytes.pipe"; @NgModule({ @@ -28,6 +38,12 @@ import {HasPropertyPipe} from "./pipes/has-property.pipe"; BusyDialogComponent, SelectableComponent, HasPropertyPipe, + DrawerPageComponent, + DrawerPageSideComponent, + DrawerPageContentComponent, + FlapButtonComponent, + MiddleCenteredComponent, + FormatBytesPipe, ], exports: [ ConfirmDialogComponent, @@ -38,15 +54,24 @@ import {HasPropertyPipe} from "./pipes/has-property.pipe"; MetadataEntryComponent, SelectableComponent, HasPropertyPipe, + DrawerPageComponent, + DrawerPageSideComponent, + DrawerPageContentComponent, + FlapButtonComponent, + MiddleCenteredComponent, + FormatBytesPipe, ], imports: [ CommonModule, - NgIconsModule.withIcons({}), + NgIconsModule.withIcons({ MatChevronLeft, MatChevronRight }), MatProgressSpinnerModule, MatButtonModule, MatDialogModule, MatMenuModule, - MatProgressBarModule + MatProgressBarModule, + MatSidenavModule, + FlexLayoutModule, + MatRippleModule ] }) export class AppCommonModule { diff --git a/mediarepo-ui/src/app/components/shared/app-common/busy-dialog/busy-dialog.component.html b/mediarepo-ui/src/app/components/shared/app-common/busy-dialog/busy-dialog.component.html index e0a5027..c744725 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/busy-dialog/busy-dialog.component.html +++ b/mediarepo-ui/src/app/components/shared/app-common/busy-dialog/busy-dialog.component.html @@ -6,7 +6,7 @@ {{message}}
-
diff --git a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.html b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.html index 4009d30..ded2930 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.html +++ b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.html @@ -1,5 +1,14 @@
- + + + +
+
+
+
diff --git a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.scss b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.scss index 63724c8..8c35839 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.scss +++ b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.scss @@ -1,3 +1,13 @@ +@import "src/colors"; + +:host { + display: block; + position: relative; + height: 100%; + width: 100%; + margin: 0; +} + .busy-indicator-overlay { position: absolute; top: 0; @@ -5,12 +15,16 @@ height: 100%; width: 100%; overflow: hidden; - display: flex; + display: block; z-index: 998; mat-progress-spinner { z-index: 999; - margin: auto; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: block; } } @@ -26,9 +40,80 @@ hidden { display: none; } -::ng-deep app-busy-indicator { - width: 100%; - height: 100%; - position: relative; + +.loading-indicator-pulse-outer { + display: flex; + background-color: $primary; + animation-name: pulse-outer; + animation-duration: 2.5s; + border-radius: 1em; + width: 2em; + height: 2em; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; +} + +.loading-indicator-pulse-inner { display: block; + margin: auto; + background-color: $primary-lighter-10; + animation-name: pulse-inner; + animation-duration: 2.5s; + border-radius: 0.5em; + width: 1em; + height: 1em; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; +} + +@keyframes pulse-outer { + 2% { + border-radius: 1em; + width: 2em; + height: 2em; + } + + 48% { + border-radius: 2em; + width: 4em; + height: 4em; + } + + 52% { + border-radius: 2em; + width: 4em; + height: 4em; + } + + 98% { + border-radius: 1em; + width: 2em; + height: 2em; + } +} + +@keyframes pulse-inner { + 15% { + border-radius: 0.5em; + width: 1em; + height: 1em; + } + + 55% { + border-radius: 1.75em; + width: 2.5em; + height: 2.5em; + } + + 65% { + border-radius: 1.75em; + width: 2.5em; + height: 2.5em; + } + + 100% { + border-radius: 0.5em; + width: 1em; + height: 1em; + } } diff --git a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.ts b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.ts index 69e10b6..f9e0c7c 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.ts +++ b/mediarepo-ui/src/app/components/shared/app-common/busy-indicator/busy-indicator.component.ts @@ -12,6 +12,7 @@ export class BusyIndicatorComponent implements OnChanges { @Input() blurBackground: boolean = false; @Input() darkenBackground: boolean = false; @Input() mode: ProgressSpinnerMode = "indeterminate"; + @Input() indicatorType: "spinner" | "pulse" = "spinner"; @Input() value: number | undefined; constructor(private changeDetector: ChangeDetectorRef) { diff --git a/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.html b/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.html index aba12b2..2cca033 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.html +++ b/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.html @@ -1,5 +1,6 @@
-
diff --git a/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.ts b/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.ts index 64ecbb3..22b7187 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.ts +++ b/mediarepo-ui/src/app/components/shared/app-common/content-aware-image/content-aware-image.component.ts @@ -1,32 +1,73 @@ -import {Component, ElementRef, Input, OnInit, ViewChild} from "@angular/core"; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + DoCheck, + ElementRef, + EventEmitter, + Input, + OnDestroy, + OnInit, + Output, + ViewChild +} from "@angular/core"; import {SafeResourceUrl} from "@angular/platform-browser"; @Component({ selector: "app-content-aware-image", templateUrl: "./content-aware-image.component.html", - styleUrls: ["./content-aware-image.component.scss"] + styleUrls: ["./content-aware-image.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ContentAwareImageComponent implements OnInit { - +export class ContentAwareImageComponent implements OnInit, DoCheck, OnDestroy { @Input() imageSrc!: string | SafeResourceUrl; @Input() maximizeHeight: boolean = true; @Input() maximizeWidth: boolean = true; @Input() borderRadius: string | undefined; @Input() decoding: "async" | "sync" | "auto" = "auto"; - - @ViewChild("image") image: ElementRef | undefined; + @Input() maxRetry = 3; + @Input() retryDelay = 200; + @ViewChild("image") imageElement?: ElementRef; + @ViewChild("imageContainer") imageContainer?: ElementRef; + @Output() appLoadEnd = new EventEmitter(); + @Output() appLoadError = new EventEmitter(); scaleWidth = false; + private previousHeight = 0; + private previousWidth = 0; + private retryCount = 0; + private readonly checkInterval?: number; - constructor() { + constructor(private changeDetector: ChangeDetectorRef) { + this.checkInterval = setInterval(() => this.checkSize(), 1000); } public ngOnInit(): void { - if (this.image) { - this.image.nativeElement.decoding = this.decoding; + if (this.imageElement) { + this.imageElement.nativeElement.decoding = this.decoding; + this.changeDetector.detach(); + } + } + + public ngOnDestroy(): void { + clearInterval(this.checkInterval); + } + + public ngDoCheck(): void { + this.checkSize(); + } + + public checkSize(): void { + if (this.imageElement?.nativeElement && this.imageContainer?.nativeElement) { + this.adjustSize(this.imageElement.nativeElement, this.imageContainer.nativeElement); } } + public onImageLoad(image: HTMLImageElement, imageContainer: HTMLDivElement): void { + this.adjustSize(image, imageContainer); + this.appLoadEnd.emit(); + } + /** * Fits the image into the container * @param {HTMLImageElement} image @@ -35,8 +76,31 @@ export class ContentAwareImageComponent implements OnInit { public adjustSize(image: HTMLImageElement, imageContainer: HTMLDivElement): void { const containerHeight = Math.abs(imageContainer.clientHeight); const containerWidth = Math.abs(imageContainer.clientWidth); - const imageRelativeHeight = image.naturalHeight / containerHeight; - const imageRelativeWidth = image.naturalWidth / containerWidth; - this.scaleWidth = imageRelativeWidth > imageRelativeHeight; + + if (this.previousWidth != containerWidth || this.previousHeight != containerHeight) { + this.previousHeight = containerHeight; + this.previousWidth = containerWidth; + const imageRelativeHeight = image.naturalHeight / containerHeight; + const imageRelativeWidth = image.naturalWidth / containerWidth; + const scaleWidth = imageRelativeWidth > imageRelativeHeight; + + if (scaleWidth != this.scaleWidth) { + this.scaleWidth = scaleWidth; + this.changeDetector.detectChanges(); + } + } + } + + public onImageLoadError(error: ErrorEvent, image: HTMLImageElement): void { + const imageSrc = image.src; + + if (this.retryCount < this.maxRetry) { + this.retryCount++; + setTimeout(() => { + image.src = imageSrc; + }, this.retryDelay * this.retryCount); + } else { + this.appLoadError.emit(); + } } } diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.html b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.html new file mode 100644 index 0000000..6dbc743 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.html @@ -0,0 +1 @@ + diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.scss b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.spec.ts new file mode 100644 index 0000000..9c0599d --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {DrawerPageContentComponent} from "./drawer-page-content.component"; + +describe("DrawerPageContentComponent", () => { + let component: DrawerPageContentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DrawerPageContentComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DrawerPageContentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.ts new file mode 100644 index 0000000..cf624ac --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-content/drawer-page-content.component.ts @@ -0,0 +1,13 @@ +import {ChangeDetectionStrategy, Component} from "@angular/core"; + +@Component({ + selector: "app-drawer-page-content", + templateUrl: "./drawer-page-content.component.html", + styleUrls: ["./drawer-page-content.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DrawerPageContentComponent { + + constructor() { + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.html b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.html new file mode 100644 index 0000000..6dbc743 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.html @@ -0,0 +1 @@ + diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.scss b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.spec.ts new file mode 100644 index 0000000..dbe9360 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {DrawerPageSideComponent} from "./drawer-page-side.component"; + +describe("DrawerPageSideComponent", () => { + let component: DrawerPageSideComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DrawerPageSideComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DrawerPageSideComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.ts new file mode 100644 index 0000000..1804d1e --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page-side/drawer-page-side.component.ts @@ -0,0 +1,13 @@ +import {ChangeDetectionStrategy, Component} from "@angular/core"; + +@Component({ + selector: "app-drawer-page-side", + templateUrl: "./drawer-page-side.component.html", + styleUrls: ["./drawer-page-side.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DrawerPageSideComponent { + + constructor() { + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.html b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.html new file mode 100644 index 0000000..061f252 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.scss b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.scss new file mode 100644 index 0000000..dcc26f8 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.scss @@ -0,0 +1,39 @@ +@import "src/colors"; + +mat-drawer { + height: 100%; + width: 25%; + overflow: hidden; +} + +mat-drawer-content { + overflow-x: hidden; + overflow-y: auto; + height: 100%; +} + +mat-drawer-container { + height: 100%; + width: 100%; + overflow: hidden; +} + +.drawer-side-inner { + width: 100%; + height: 100%; + display: block; + margin: 0; +} + +.drawer-side-top-bar { + background: $background; +} + +.collapse-button { + height: 2em; + float: right; + + ng-icon { + margin-top: -0.5em; + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.spec.ts new file mode 100644 index 0000000..28db033 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {DrawerPageComponent} from "./drawer-page.component"; + +describe("DrawerPageComponent", () => { + let component: DrawerPageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DrawerPageComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DrawerPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.ts b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.ts new file mode 100644 index 0000000..7f7de03 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/drawer-page/drawer-page.component.ts @@ -0,0 +1,23 @@ +import {ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Output} from "@angular/core"; + +@Component({ + selector: "app-drawer-page", + templateUrl: "./drawer-page.component.html", + styleUrls: ["./drawer-page.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class DrawerPageComponent { + + public drawerOpened = true; + + @Output() appSizeChange = new EventEmitter(); + + constructor(private changeDetecter: ChangeDetectorRef) { + } + + public toggleDrawer(): void { + this.drawerOpened = !this.drawerOpened; + this.appSizeChange.emit(); + this.changeDetecter.markForCheck(); + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.html b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.html new file mode 100644 index 0000000..1b0d07d --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.html @@ -0,0 +1,5 @@ +
+ +
diff --git a/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.scss b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.scss new file mode 100644 index 0000000..87d9c8b --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.scss @@ -0,0 +1,167 @@ +@import "src/colors"; + +:host { + position: absolute; + transition-duration: 0.5s; + + &:hover { + & > .flap-top, & > .flap-bottom { + height: 1.5em; + } + + & > .flap-left, & > .flap-right { + width: 1.5em; + } + } + + &[attach='left'], &[attach='right'] { + top: calc(50% - 5em); + height: 10em; + width: 2.5em; + } + + &[attach='top'], &[attach='bottom'] { + left: calc(50% - 5em); + width: 10em; + height: 2.5em; + } + + &[attach='left'] { + left: 0; + } + + &[attach='right'] { + right: 0; + } + + &[attach='top'] { + top: 0; + } + + &[attach='bottom'] { + bottom: 0; + } + + &[attach='left'], &[attach='top'][align='start'], &[attach='bottom'][align='start'] { + .flap-button { + left: 0; + } + } + + &[attach='right'], &[attach='top'][align='end'], &[attach='bottom'][align='end'] { + .flap-button { + right: 0; + } + } + + &[attach='top'], &[attach='left'][align='start'], &[attach='right'][align='start'] { + .flap-button { + top: 0; + } + } + + &[attach='bottom'], &[attach='left'][align='end'], &[attach='right'][align='end'] { + .flap-button { + bottom: 0; + } + } + + &[attach='left'][align='center'], &[attach='right'][align='center'] { + .flap-button { + top: 50%; + transform: translate(0, -50%); + } + } + + &[attach='top'][align='center'], &[attach='bottom'][align='center'] { + .flap-button { + left: 50%; + transform: translate(-50%, 0); + } + } +} + +.flap-button { + position: absolute; + display: flex; + opacity: 0.7; + background: $accent-darker-10; + text-align: center; + transition-duration: 0.1s; + overflow: hidden; + + &:hover { + background: $accent; + opacity: 0.9; + cursor: pointer; + transition: 0.5s; + } + + ::ng-deep ng-icon { + margin: auto; + } +} + + +.flap-top, .flap-bottom { + width: 4em; + height: 2px; +} + +.flap-button.flap-top:hover, .flap-button.flap-bottom:hover { + width: 10em; + height: 2em; +} + +.flap-left, .flap-right { + width: 2px; + height: 4em; +} + +.flap-button.flap-left:hover, .flap-button.flap-right:hover { + width: 2em; + height: 10em; +} + +$flap-border-radius: 2em; + +.flap-start.flap-left, .flap-start.flap-top { + border-bottom-right-radius: $flap-border-radius; +} + +.flap-start.flap-right, .flap-end.flap-top { + border-bottom-left-radius: $flap-border-radius; +} + +.flap-end.flap-left, .flap-start.flap-bottom { + border-top-right-radius: $flap-border-radius; +} + +.flap-end.flap-right, .flap-end.flap-bottom { + border-top-left-radius: $flap-border-radius; +} + +.flap-center { + + &.flap-left { + border-top-right-radius: $flap-border-radius; + border-bottom-right-radius: $flap-border-radius; + } + + &.flap-right { + border-top-left-radius: $flap-border-radius; + border-bottom-left-radius: $flap-border-radius; + } + + &.flap-top { + border-bottom-right-radius: $flap-border-radius; + border-bottom-left-radius: $flap-border-radius; + } + + &.flap-bottom { + border-top-right-radius: $flap-border-radius; + border-top-left-radius: $flap-border-radius; + } +} + + diff --git a/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.spec.ts new file mode 100644 index 0000000..6787e1e --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {FlapButtonComponent} from "./flap-button.component"; + +describe("FlapButtonComponent", () => { + let component: FlapButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [FlapButtonComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FlapButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.ts b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.ts new file mode 100644 index 0000000..b04f872 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/flap-button/flap-button.component.ts @@ -0,0 +1,20 @@ +import {ChangeDetectionStrategy, Component, EventEmitter, Input, Output} from "@angular/core"; + +export type Attachment = "top" | "bottom" | "left" | "right"; +export type Alignment = "start" | "center" | "end"; + +@Component({ + selector: "app-flap-button", + templateUrl: "./flap-button.component.html", + styleUrls: ["./flap-button.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class FlapButtonComponent { + + @Input() attach: Attachment = "top"; + @Input() align: Alignment = "center"; + @Output() appClick = new EventEmitter(); + + constructor() { + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.html b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.html new file mode 100644 index 0000000..6dbc743 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.html @@ -0,0 +1 @@ + diff --git a/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.scss b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.scss new file mode 100644 index 0000000..cca5550 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.scss @@ -0,0 +1,7 @@ +:host { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.spec.ts new file mode 100644 index 0000000..412d10b --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from "@angular/core/testing"; + +import {MiddleCenteredComponent} from "./middle-centered.component"; + +describe("MiddleCenteredComponent", () => { + let component: MiddleCenteredComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [MiddleCenteredComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MiddleCenteredComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.ts b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.ts new file mode 100644 index 0000000..93606d0 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/middle-centered/middle-centered.component.ts @@ -0,0 +1,13 @@ +import {ChangeDetectionStrategy, Component} from "@angular/core"; + +@Component({ + selector: "app-middle-centered", + templateUrl: "./middle-centered.component.html", + styleUrls: ["./middle-centered.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class MiddleCenteredComponent { + + constructor() { + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.spec.ts b/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.spec.ts new file mode 100644 index 0000000..540c722 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.spec.ts @@ -0,0 +1,8 @@ +import {FormatBytesPipe} from "./format-bytes.pipe"; + +describe("FormatBytesPipe", () => { + it("create an instance", () => { + const pipe = new FormatBytesPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.ts b/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.ts new file mode 100644 index 0000000..6260cc5 --- /dev/null +++ b/mediarepo-ui/src/app/components/shared/app-common/pipes/format-bytes.pipe.ts @@ -0,0 +1,24 @@ +import {Pipe, PipeTransform} from "@angular/core"; + +@Pipe({ + name: "formatBytes" +}) +export class FormatBytesPipe implements PipeTransform { + + static round(number: number, decimals: number) { + return Math.round(number * (10 ** decimals)) / (10 ** decimals); + } + + transform(value: number): string { + const units = ["B", "KiB", "MiB", "GiB"]; + let formattedValue = value; + + for (const unit of units) { + if (formattedValue < 1000) { + return `${formattedValue} ${unit}`; + } + formattedValue = FormatBytesPipe.round(formattedValue / 1024, 2); + } + return formattedValue + " GiB"; + } +} diff --git a/mediarepo-ui/src/app/components/shared/app-common/selectable/selectable.component.scss b/mediarepo-ui/src/app/components/shared/app-common/selectable/selectable.component.scss index 33b3125..88d7877 100644 --- a/mediarepo-ui/src/app/components/shared/app-common/selectable/selectable.component.scss +++ b/mediarepo-ui/src/app/components/shared/app-common/selectable/selectable.component.scss @@ -1,5 +1,7 @@ +@import "src/colors"; + .selectable.selected { - background-color: #5c5c5c; + background-color: $background-lighter-10; } body { diff --git a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.html b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.html index 560a71f..4953a1a 100644 --- a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.html +++ b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.html @@ -10,7 +10,14 @@
- + + +
diff --git a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.scss b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.scss index 5dbd2ae..eaccded 100644 --- a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.scss +++ b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.scss @@ -1,3 +1,8 @@ +@import "src/colors"; + +.image-full-view-inner { + background-color: $background-darker-05; +} .image-drag-container, .image-scale-container { height: 100%; @@ -33,3 +38,7 @@ display: block; position: relative; } + +.hidden { + display: none; +} diff --git a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.ts b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.ts index b15a4f6..92144e6 100644 --- a/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.ts +++ b/mediarepo-ui/src/app/components/shared/file/content-viewer/image-viewer/image-viewer.component.ts @@ -13,12 +13,15 @@ export class ImageViewerComponent implements OnChanges { public imagePosition = { x: 0, y: 0 }; public mouseInImageView = false; + public loading = true; + constructor() { } public ngOnChanges(changes: SimpleChanges): void { if (changes["imageUrl"]) { this.resetImage(); + this.loading = true; } } diff --git a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component-theme.scss b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component-theme.scss deleted file mode 100644 index 83f1083..0000000 --- a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component-theme.scss +++ /dev/null @@ -1,26 +0,0 @@ -@use 'sass:map'; -@use '../../../../../../node_modules/@angular/material/index' as mat; - -@mixin color($theme) { - $color-config: mat.get-color-config($theme); - $primary-palette: map.get($color-config, 'primary'); - - mat-card.selected { - background-color: mat.get-color-from-palette($primary-palette, 'darker'); - } -} - -@mixin typography($theme) { -} - -@mixin theme($theme) { - $color-config: mat.get-color-config($theme); - @if $color-config != null { - @include color($theme); - } - - $typography-config: mat.get-typography-config($theme); - @if $typography-config != null { - @include typography($theme); - } -} diff --git a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.html b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.html index f4eb5e6..1856588 100644 --- a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.html +++ b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.html @@ -1,11 +1,13 @@ - - - - - - - +
+ + + + +
diff --git a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.scss b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.scss index 8ae08df..0c8c76c 100644 --- a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.scss +++ b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.scss @@ -1,21 +1,35 @@ -mat-card { - height: calc(100% - 32px); - width: calc(100% - 32px); - user-select: none; +@import "src/colors"; + +:host { + display: block; + overflow: hidden; + border-radius: 5px; cursor: pointer; + user-select: none; + position: relative; } -mat-card-content { +.file-card-inner { + background-color: $background-lighter-05; height: 100%; width: 100%; -} + margin: 0; + display: flex; + position: relative; -app-busy-indicator { - height: 100%; - width: 100%; + &.selected { + background-color: $primary-darker-10; + } } .entry-image { - width: 100%; - height: 100%; + margin: 10px; + height: calc(100% - 20px); + width: calc(100% - 20px); + display: flex; +} + + +.hidden { + display: none; } diff --git a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.ts b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.ts index 9ddb1c6..1936c67 100644 --- a/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.ts +++ b/mediarepo-ui/src/app/components/shared/file/file-card/file-card.component.ts @@ -2,15 +2,13 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, - SimpleChanges, - ViewChild + SimpleChanges } from "@angular/core"; import {File} from "../../../../../api/models/File"; import {Selectable} from "../../../../models/Selectable"; @@ -26,7 +24,7 @@ const LOADING_WORK_KEY = "FILE_THUMBNAIL_LOADING"; changeDetection: ChangeDetectionStrategy.OnPush }) export class FileCardComponent implements OnInit, OnChanges, OnDestroy { - @ViewChild("card") card!: ElementRef; + @Input() public entry!: Selectable; @Input() public fileChanged: BehaviorSubject = new BehaviorSubject(undefined); @Output() clickEvent = new EventEmitter(); @@ -41,13 +39,13 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy { async ngOnInit() { this.cachedId = this.entry.data.id; - this.setImageDelayed(); + this.loading = true; } async ngOnChanges(changes: SimpleChanges) { if (changes["entry"] && (this.cachedId === undefined || this.entry.data.id !== this.cachedId)) { this.cachedId = this.entry.data.id; - this.setImageDelayed(); + this.loading = true; } if (changes["fileChanged"]) { this.fileChanged.subscribe(() => this.changeDetector.markForCheck()); @@ -60,6 +58,11 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy { } } + public onClick(): void { + console.debug(this.entry.data.id); + this.clickEvent.emit(this); + } + private setImageDelayed() { if (this.workId) { this.schedulingService.cancelWork(LOADING_WORK_KEY, this.workId); @@ -68,7 +71,7 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy { this.workId = this.schedulingService.addWork( LOADING_WORK_KEY, async () => { - await this.schedulingService.delay(1); + await this.schedulingService.delay(0); this.loading = false; this.changeDetector.markForCheck(); } diff --git a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html index 291cf61..281b9bc 100644 --- a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html +++ b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html @@ -1,23 +1,32 @@ - + +

{{this.state.files.value.length}} files found + in {{this.searchDuration < 0.1 ? " < 0.1" : this.searchDuration}} + seconds

-

Tags

+

{{contextTags.length}} Tags

diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.scss index e4273c7..8b33c96 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.scss +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.scss @@ -1,3 +1,5 @@ +@import "src/colors"; + .full-width { width: auto; min-width: 100%; @@ -7,7 +9,6 @@ width: calc(100% - 64px); height: 2.7em; padding: 0.5em 0; - box-shadow: 0 0 1em 0.1em rgba(0, 0, 0, 0.05) inset; overflow-x: auto; overflow-y: hidden; } @@ -19,6 +20,11 @@ height: calc(3em + 10px); } +.search-result-display { + text-align: center; + width: 100%; +} + #delete-all-tags-button { position: absolute; top: 0; @@ -79,21 +85,22 @@ cursor: pointer; user-select: none; font-size: 1.2em; - transition-duration: 0.1s; + transition-duration: 0.2s; width: 100%; + background-color: $background-lighter-05; - app-tag-item { - margin: auto auto auto 0.25em; + &:hover { + background-color: $background-lighter-10; } -} -.selectable-tag:hover { - background-color: darken(dimgrey, 10); -} + &:active { + cursor: pointer; + background-color: $background; + } -.selectable-tag:active { - cursor: pointer; - background-color: darken(dimgrey, 5); + app-tag-item { + margin: auto auto auto 0.25em; + } } cdk-virtual-scroll-viewport { @@ -132,3 +139,21 @@ mat-divider { margin-left: 1em; margin-right: 1em; } + +.tag-input-item { + background-color: $background-lighter-10; + border-radius: 1em; + transition-duration: 0.2s; + + &:hover { + background-color: $background-lighter-15; + } +} + +mat-form-field:focus { + background-color: dimgrey; +} + +#sort-button { + background-color: $background-lighter-10; +} diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts index 7c6f149..fe88675 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts @@ -15,7 +15,7 @@ import {LoggingService} from "../../../../services/logging/logging.service"; import {FilterDialogComponent} from "./filter-dialog/filter-dialog.component"; import {Tag} from "../../../../../api/models/Tag"; import {clipboard} from "@tauri-apps/api"; -import {TabState} from "../../../../models/TabState"; +import {FilesTabState} from "../../../../models/state/FilesTabState"; import {FilterQueryBuilder} from "../../../../../api/models/FilterQueryBuilder"; import {SearchFilters} from "../../../../../api/models/SearchFilters"; import {FileStatus, FilterExpression,} from "../../../../../api/api-types/files"; @@ -37,7 +37,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit { @Input() availableTags: Tag[] = []; @Input() contextTags: Tag[] = []; - @Input() state!: TabState; + @Input() state!: FilesTabState; @Input() tagsLoading = false; @Output() searchStartEvent = new EventEmitter(); @@ -53,8 +53,10 @@ export class FileSearchComponent implements AfterViewChecked, OnInit { public displayImported = true; public displayArchived = true; public displayDeleted = false; + public searchDuration = 0; private needsScroll = false; + private searchStart = Date.now(); constructor( private logger: LoggingService, @@ -69,6 +71,13 @@ export class FileSearchComponent implements AfterViewChecked, OnInit { this.assignDisplayedFilters(); }); this.state.sortingPreset.subscribe(s => this.sortingPreset = s); + this.state.loading.subscribe(l => { + if (l) { + this.searchStart = Date.now(); + } else { + this.searchDuration = Math.round((Date.now() - this.searchStart) / 100) / 10; + } + }); this.applyStatusFromFilters(); this.needsScroll = true; this.assignDisplayedFilters(); diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/filter-dialog/filter-expression-list-item/filter-expression-list-item.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/filter-dialog/filter-expression-list-item/filter-expression-list-item.component.scss index b1636ed..6508331 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/filter-dialog/filter-expression-list-item/filter-expression-list-item.component.scss +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/filter-dialog/filter-expression-list-item/filter-expression-list-item.component.scss @@ -1,8 +1,10 @@ +@import "src/colors"; + mat-list { height: 100%; width: 100%; display: block; - background-color: #353535; + background-color: $background; padding: 0; border-radius: 0.25em; } @@ -22,7 +24,7 @@ mat-list-item.or-filter-list-item { } .selected { - background-color: #5c5c5c; + background-color: $background-lighter-10; } app-selectable { @@ -31,5 +33,5 @@ app-selectable { } .or-combinator { - color: #7dff70; + color: $accent-lighter-10; } diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss index 4448aea..fc2b800 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss @@ -6,4 +6,8 @@ background-color: $background-lighter-10; text-overflow: ellipsis; overflow: hidden; + + &:hover { + background-color: $background-lighter-15; + } } diff --git a/mediarepo-ui/src/app/components/shared/sidebar/tag-edit/tag-edit.component.html b/mediarepo-ui/src/app/components/shared/sidebar/tag-edit/tag-edit.component.html index 388fc69..b7f2b84 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/tag-edit/tag-edit.component.html +++ b/mediarepo-ui/src/app/components/shared/sidebar/tag-edit/tag-edit.component.html @@ -1,6 +1,7 @@ -
+

Edit Tags

+

{{tags.length}} Tags

diff --git a/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.scss b/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.scss index 5a9d645..e0dbeb8 100644 --- a/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.scss +++ b/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.scss @@ -1,11 +1,18 @@ @import "src/colors"; +:host { + height: 100%; + overflow: hidden; + display: flex; +} + .tag-item-wrapper { - display: inline; width: 100%; padding: 0.25em; - word-break: break-all; text-overflow: ellipsis; + word-break: keep-all; + overflow: hidden; + margin: auto; } .tag-item-namespace { diff --git a/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.ts b/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.ts index e18418a..14155b9 100644 --- a/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.ts +++ b/mediarepo-ui/src/app/components/shared/tag/tag-item/tag-item.component.ts @@ -1,10 +1,11 @@ -import {Component, Input} from "@angular/core"; +import {ChangeDetectionStrategy, Component, Input} from "@angular/core"; import {Tag} from "../../../../../api/models/Tag"; @Component({ selector: "app-tag-item", templateUrl: "./tag-item.component.html", - styleUrls: ["./tag-item.component.scss"] + styleUrls: ["./tag-item.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TagItemComponent { diff --git a/mediarepo-ui/src/app/models/AppState.ts b/mediarepo-ui/src/app/models/AppState.ts deleted file mode 100644 index 923e4c3..0000000 --- a/mediarepo-ui/src/app/models/AppState.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {TabState} from "./TabState"; -import {FileService} from "../services/file/file.service"; -import {BehaviorSubject} from "rxjs"; -import {TabCategory} from "./TabCategory"; - -export class AppState { - - public tabs = new BehaviorSubject([]); - public selectedTab = new BehaviorSubject(undefined); - public repoName: string | undefined; - private tabIdCounter = 0; - private readonly fileService: FileService; - - constructor(fileService: FileService) { - this.fileService = fileService; - } - - public static deserializeJson(stateString: string, fileService: FileService): AppState { - let state = JSON.parse(stateString); - let appState = new AppState(fileService); - const tabs = state.tabs.map((tab: any) => TabState.fromDTO(tab, fileService)); - appState.tabs.next(tabs); - - appState.tabIdCounter = state.tabIdCounter; - appState.selectedTab.next(state.selectedTab); - appState.repoName = state.repoName; - - return appState; - } - - public addTab(category: TabCategory): TabState { - const state = new TabState(this.tabIdCounter++, category, this.fileService); - this.tabs.next([...this.tabs.value, state]); - return state; - } - - public async closeTab(uuid: number) { - const index = this.tabs.value.findIndex(t => t.uuid === uuid); - const tabs = this.tabs.value; - tabs.splice(index, 1); - this.tabs.next(tabs); - } - - public serializeJson(): string { - const tabDTOs = this.tabs.value.map(tab => tab.getDTO()); - return JSON.stringify({ - repoName: this.repoName, - tabs: tabDTOs, - tabIdCounter: this.tabIdCounter, - selectedTab: this.selectedTab.value, - }); - } -} diff --git a/mediarepo-ui/src/app/models/TabState.ts b/mediarepo-ui/src/app/models/TabState.ts deleted file mode 100644 index fc75b1b..0000000 --- a/mediarepo-ui/src/app/models/TabState.ts +++ /dev/null @@ -1,96 +0,0 @@ -import {BehaviorSubject} from "rxjs"; -import {TabCategory} from "./TabCategory"; -import {FileService} from "../services/file/file.service"; -import {File} from "../../api/models/File"; -import {SortKey} from "../../api/models/SortKey"; -import {debounceTime} from "rxjs/operators"; -import {mapNew} from "../../api/models/adaptors"; -import {SearchFilters} from "../../api/models/SearchFilters"; -import {SortingPreset} from "../../api/models/SortingPreset"; - -export class TabState { - public uuid: number; - public category: TabCategory; - public mode = new BehaviorSubject<"grid" | "gallery">("grid"); - public selectedCD = new BehaviorSubject(undefined); - public loading = new BehaviorSubject(false); - - public files = new BehaviorSubject([]); - public filters = new BehaviorSubject(new SearchFilters([])); - public sortingPreset = new BehaviorSubject(SortingPreset.fromValues( - -1, - [SortKey.fromValues( - "FileImportedTime", - "Ascending", - undefined - )] - )); - - private fileService: FileService; - - constructor( - uuid: number, - category: TabCategory, - fileService: FileService - ) { - this.category = category; - this.uuid = uuid; - this.fileService = fileService; - if (this.category === TabCategory.Files) { - this.filters.pipe(debounceTime(500)) - .subscribe(async () => await this.findFiles()); - this.sortingPreset.pipe(debounceTime(100)) - .subscribe(async () => await this.findFiles()); - } - } - - public static fromDTO( - dto: any, - fileService: FileService - ): TabState { - const state = new TabState( - dto.uuid, - dto.category, - fileService - ); - - state.filters.next(new SearchFilters(dto.filters ?? [])); - state.sortingPreset.next(new SortingPreset(dto.sortingPreset)); - state.mode.next(dto.mode ?? "grid"); - state.selectedCD.next(dto.selectedFileHash); - state.files.next((dto.files ?? []).map(mapNew(File))); - - return state; - } - - public async findFiles() { - this.loading.next(true); - const files = await this.fileService.findFiles( - this.filters.value, - this.sortingPreset.value.sortKeys - ); - this.files.next(files); - this.loading.next(false); - } - - public setTagFilters(filters: SearchFilters) { - this.filters.next(filters); - } - - public setSortingPreset(preset: SortingPreset) { - this.sortingPreset.next(preset); - } - - public getDTO(): any { - return { - uuid: this.uuid, - category: this.category, - filters: this.filters.value.getFilters(), - sortingPreset: this.sortingPreset.value.rawData, - mode: this.mode.value, - selectedFileHash: this.selectedCD.value, - files: this.category === TabCategory.Import ? this.files.value.map( - f => f.rawData) : [], - }; - } -} diff --git a/mediarepo-ui/src/app/models/TagQuery.ts b/mediarepo-ui/src/app/models/TagQuery.ts deleted file mode 100644 index 6757559..0000000 --- a/mediarepo-ui/src/app/models/TagQuery.ts +++ /dev/null @@ -1,16 +0,0 @@ -export class TagQuery { - constructor(public tag: string, public negate: boolean) { - } - - public static fromString(tag: string): TagQuery { - if (tag.startsWith("-")) { - return new TagQuery(tag.replace(/^-/g, ""), true); - } else { - return new TagQuery(tag, false); - } - } - - public getNormalizedTag(): string { - return this.negate ? "-" + this.tag : this.tag; - } -} diff --git a/mediarepo-ui/src/app/models/rust-types.ts b/mediarepo-ui/src/app/models/rust-types.ts deleted file mode 100644 index 01b054f..0000000 --- a/mediarepo-ui/src/app/models/rust-types.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type RustEnum = { - [key: string]: VariantData -}; - -export function createRustEnum(variant: string, data: VariantData): T { - let enumInstance: RustEnum = {}; - enumInstance[variant] = data; - - return enumInstance as unknown as T; -} diff --git a/mediarepo-ui/src/app/models/state/AppState.ts b/mediarepo-ui/src/app/models/state/AppState.ts new file mode 100644 index 0000000..b1b5559 --- /dev/null +++ b/mediarepo-ui/src/app/models/state/AppState.ts @@ -0,0 +1,75 @@ +import {FilesTabSaveState, FilesTabState} from "./FilesTabState"; +import {BehaviorSubject} from "rxjs"; +import {TabCategory} from "./TabCategory"; +import {TabSaveState, TabState} from "./TabState"; +import {StateServices} from "./StateServices"; +import {ImportTabSaveState, ImportTabState} from "./ImportTabState"; + +export class AppState { + + public tabs = new BehaviorSubject([]); + public selectedTab = new BehaviorSubject(undefined); + public repoName: string | undefined; + private tabIdCounter = 0; + private readonly services: StateServices; + + constructor(services: StateServices) { + this.services = services; + } + + public static deserializeJson(stateString: string, services: StateServices): AppState { + let state = JSON.parse(stateString); + let appState = new AppState(services); + + const tabs = state.tabs.map((saveState: TabSaveState) => { + let tab; + + if (saveState.category === TabCategory.Files) { + tab = new FilesTabState(saveState.uuid, services); + tab.restoreSaveState(saveState as FilesTabSaveState); + } else if (saveState.category === TabCategory.Import) { + tab = new ImportTabState(saveState.uuid, services); + tab.restoreSaveState(saveState as ImportTabSaveState); + } + + return tab; + }); + appState.tabs.next(tabs); + + appState.tabIdCounter = state.tabIdCounter; + appState.selectedTab.next(state.selectedTab); + appState.repoName = state.repoName; + + return appState; + } + + public addTab(category: TabCategory): TabState { + let state; + + if (category == TabCategory.Files) { + state = new FilesTabState(this.tabIdCounter++, this.services); + } else { + state = new ImportTabState(this.tabIdCounter++, this.services); + } + + this.tabs.next([...this.tabs.value, state]); + return state; + } + + public async closeTab(uuid: number) { + const index = this.tabs.value.findIndex(t => t.uuid === uuid); + const tabs = this.tabs.value; + tabs.splice(index, 1); + this.tabs.next(tabs); + } + + public serializeJson(): string { + const tabDTOs = this.tabs.value.map(tab => tab.toSaveState()); + return JSON.stringify({ + repoName: this.repoName, + tabs: tabDTOs, + tabIdCounter: this.tabIdCounter, + selectedTab: this.selectedTab.value, + }); + } +} diff --git a/mediarepo-ui/src/app/models/state/FilesTabState.ts b/mediarepo-ui/src/app/models/state/FilesTabState.ts new file mode 100644 index 0000000..332b169 --- /dev/null +++ b/mediarepo-ui/src/app/models/state/FilesTabState.ts @@ -0,0 +1,101 @@ +import {BehaviorSubject, skip} from "rxjs"; +import {TabCategory} from "./TabCategory"; +import {File} from "../../../api/models/File"; +import {SortKey} from "../../../api/models/SortKey"; +import {debounceTime} from "rxjs/operators"; +import {mapNew} from "../../../api/models/adaptors"; +import {SearchFilters} from "../../../api/models/SearchFilters"; +import {SortingPreset} from "../../../api/models/SortingPreset"; +import {TabSaveState, TabState} from "./TabState"; +import {StateServices} from "./StateServices"; +import {FileBasicData, FilterExpression} from "../../../api/api-types/files"; +import {SortingPresetData} from "../../../api/api-types/presets"; +import {SaveState} from "./SaveState"; + +export type FilesTabSaveState = { + mode: "gallery" | "grid", + selectedCd: string | undefined, + files: FileBasicData[], + filters: FilterExpression[], + sortingPreset: SortingPresetData, +} & TabSaveState; + +export class FilesTabState extends TabState implements SaveState { + + public mode = new BehaviorSubject<"grid" | "gallery">("grid"); + public selectedCD = new BehaviorSubject(undefined); + public loading = new BehaviorSubject(false); + + public files = new BehaviorSubject([]); + public filters = new BehaviorSubject(new SearchFilters([])); + public sortingPreset = new BehaviorSubject(SortingPreset.fromValues( + -1, + [SortKey.fromValues( + "FileImportedTime", + "Ascending", + undefined + )] + )); + + constructor( + uuid: number, + services: StateServices, + ) { + super(uuid, TabCategory.Files, services); + this.subscribe(); + } + + public restoreSaveState( + state: FilesTabSaveState, + ) { + super.restoreSaveState(state); + this.filters = new BehaviorSubject(new SearchFilters(state.filters ?? [])); + this.sortingPreset = new BehaviorSubject(new SortingPreset(state.sortingPreset)); + this.mode = new BehaviorSubject(state.mode ?? "grid"); + this.selectedCD = new BehaviorSubject(state.selectedCd); + this.files = new BehaviorSubject((state.files ?? []).map(mapNew(File))); + this.subscribe(); + } + + public async findFiles() { + this.loading.next(true); + const files = await this.services.fileService.findFiles( + this.filters.value, + this.sortingPreset.value.sortKeys + ); + this.files.next(files); + this.loading.next(false); + } + + public setTagFilters(filters: SearchFilters) { + this.filters.next(filters); + } + + public setSortingPreset(preset: SortingPreset) { + this.sortingPreset.next(preset); + } + + public toSaveState(): FilesTabSaveState { + return { + uuid: this.uuid, + category: this.category, + filters: this.filters.value.getFilters(), + sortingPreset: this.sortingPreset.value.rawData, + mode: this.mode.value, + selectedCd: this.selectedCD.value, + files: this.category === TabCategory.Import ? this.files.value.map( + f => f.rawData) : [], + }; + } + + private subscribe() { + this.filters + .pipe(skip(1)) + .pipe(debounceTime(500)) + .subscribe(async () => await this.findFiles()); + this.sortingPreset + .pipe(skip(1)) + .pipe(debounceTime(100)) + .subscribe(async () => await this.findFiles()); + } +} diff --git a/mediarepo-ui/src/app/models/state/ImportTabState.ts b/mediarepo-ui/src/app/models/state/ImportTabState.ts new file mode 100644 index 0000000..61bfe7f --- /dev/null +++ b/mediarepo-ui/src/app/models/state/ImportTabState.ts @@ -0,0 +1,57 @@ +import {TabSaveState, TabState} from "./TabState"; +import {SaveState} from "./SaveState"; +import {StateServices} from "./StateServices"; +import {TabCategory} from "./TabCategory"; +import {BehaviorSubject} from "rxjs"; +import {File} from "../../../api/models/File"; +import {FileBasicData, FileOsMetadata} from "../../../api/api-types/files"; +import {mapNew} from "../../../api/models/adaptors"; + +export type ImportTabSaveState = { + selectedCd: string | undefined, + mode: "grid" | "gallery", + selectedPaths: FileOsMetadata[], + files: FileBasicData[], +} & TabSaveState; + +export class ImportTabState extends TabState implements SaveState { + + public mode = new BehaviorSubject<"grid" | "gallery">("grid"); + public selectedCD = new BehaviorSubject(undefined); + public files = new BehaviorSubject([]); + public selectedPaths = new BehaviorSubject([]); + + // used when files are being imported + public importing = new BehaviorSubject(false); + public importingProgress = new BehaviorSubject(0); + public importedCount = new BehaviorSubject(0); + + constructor(uuid: number, services: StateServices) { + super(uuid, TabCategory.Import, services); + } + + public addImportedFile(file: File) { + this.files.next([...this.files.value, file]); + } + + public restoreSaveState(state: ImportTabSaveState) { + super.restoreSaveState(state); + this.selectedCD = new BehaviorSubject(state.selectedCd); + this.files = new BehaviorSubject(state.files.map(mapNew(File)) ?? []); + this.mode = new BehaviorSubject<"grid" | "gallery">(state.mode ?? "grid"); + this.selectedPaths = new BehaviorSubject(state.selectedPaths ?? []); + + return self; + } + + public toSaveState(): ImportTabSaveState { + return { + uuid: this.uuid, + category: this.category, + selectedCd: this.selectedCD.value, + files: this.files.value.map(f => f.rawData), + mode: this.mode.value, + selectedPaths: this.selectedPaths.value, + }; + } +} diff --git a/mediarepo-ui/src/app/models/state/SaveState.ts b/mediarepo-ui/src/app/models/state/SaveState.ts new file mode 100644 index 0000000..50906dd --- /dev/null +++ b/mediarepo-ui/src/app/models/state/SaveState.ts @@ -0,0 +1,5 @@ +export interface SaveState { + restoreSaveState(state: State): void; + + toSaveState(): State; +} diff --git a/mediarepo-ui/src/app/models/state/StateServices.ts b/mediarepo-ui/src/app/models/state/StateServices.ts new file mode 100644 index 0000000..0cd930a --- /dev/null +++ b/mediarepo-ui/src/app/models/state/StateServices.ts @@ -0,0 +1,6 @@ +import {FileService} from "../../services/file/file.service"; + +export class StateServices { + constructor(public fileService: FileService) { + } +} diff --git a/mediarepo-ui/src/app/models/TabCategory.ts b/mediarepo-ui/src/app/models/state/TabCategory.ts similarity index 100% rename from mediarepo-ui/src/app/models/TabCategory.ts rename to mediarepo-ui/src/app/models/state/TabCategory.ts diff --git a/mediarepo-ui/src/app/models/state/TabState.ts b/mediarepo-ui/src/app/models/state/TabState.ts new file mode 100644 index 0000000..da50cd4 --- /dev/null +++ b/mediarepo-ui/src/app/models/state/TabState.ts @@ -0,0 +1,49 @@ +import {TabCategory} from "./TabCategory"; +import {StateServices} from "./StateServices"; +import {SaveState} from "./SaveState"; +import {FilesTabState} from "./FilesTabState"; +import {ImportTabState} from "./ImportTabState"; + +export type TabSaveState = { + uuid: number, + category: TabCategory, +} + +export class TabState implements SaveState { + constructor( + public uuid: number, + public category: TabCategory, + protected services: StateServices + ) { + } + + public toSaveState(): TabSaveState { + return { + uuid: this.uuid, + category: this.category + }; + } + + public restoreSaveState(state: TabSaveState): void { + this.uuid = state.uuid; + this.category = state.category; + } + + /** + * Converts the state into a files tab state + * Warning: This should only be called when it's guaranteed that this tab is a files tab + * @returns {ImportTabState} + */ + public filesTab(): FilesTabState { + return this as unknown as FilesTabState; + } + + /** + * Converts the state into an import tab state + * Warning: This should only be called when it's guaranteed that this tab is an import tab + * @returns {ImportTabState} + */ + public importTab(): ImportTabState { + return this as unknown as ImportTabState; + } +} diff --git a/mediarepo-ui/src/app/services/file/file.service.ts b/mediarepo-ui/src/app/services/file/file.service.ts index ab783a9..512f534 100644 --- a/mediarepo-ui/src/app/services/file/file.service.ts +++ b/mediarepo-ui/src/app/services/file/file.service.ts @@ -78,7 +78,7 @@ export class FileService { */ public buildThumbnailUrl(file: File, height: number, width: number): SafeResourceUrl { return this.sanitizer.bypassSecurityTrustResourceUrl( - `thumb://${file.cd}?width=${250}&height=${250}`); + `thumb://${file.cd}?width=${height}&height=${width}`); } /** diff --git a/mediarepo-ui/src/app/services/job/job.service.ts b/mediarepo-ui/src/app/services/job/job.service.ts index 404fc08..44057c3 100644 --- a/mediarepo-ui/src/app/services/job/job.service.ts +++ b/mediarepo-ui/src/app/services/job/job.service.ts @@ -10,7 +10,7 @@ export class JobService { constructor() { } - public async runJob(jobType: JobType): Promise { - return MediarepoApi.runJob({ jobType }); + public async runJob(jobType: JobType, sync: boolean = true): Promise { + return MediarepoApi.runJob({ jobType, sync }); } } diff --git a/mediarepo-ui/src/app/services/repository/repository.service.ts b/mediarepo-ui/src/app/services/repository/repository.service.ts index aeae63b..c425e6c 100644 --- a/mediarepo-ui/src/app/services/repository/repository.service.ts +++ b/mediarepo-ui/src/app/services/repository/repository.service.ts @@ -16,6 +16,7 @@ export class RepositoryService { repositories = new BehaviorSubject([]); public selectedRepository = new BehaviorSubject( undefined); + public metadata = new BehaviorSubject(undefined); constructor(private errorBroker: LoggingService) { this.registerListener().catch(err => console.error(err)); @@ -68,6 +69,7 @@ export class RepositoryService { console.warn(err); } } + this.metadata.next(undefined); await MediarepoApi.selectRepository({ name: repo.name }); } @@ -163,7 +165,9 @@ export class RepositoryService { * @returns {Promise} */ public async getRepositoryMetadata(): Promise { - return MediarepoApi.getRepositoryMetadata(); + const metadata = await MediarepoApi.getRepositoryMetadata(); + this.metadata.next(metadata); + return metadata; } /** diff --git a/mediarepo-ui/src/app/services/scheduling/scheduling.service.ts b/mediarepo-ui/src/app/services/scheduling/scheduling.service.ts index 7bddc9b..1d9678f 100644 --- a/mediarepo-ui/src/app/services/scheduling/scheduling.service.ts +++ b/mediarepo-ui/src/app/services/scheduling/scheduling.service.ts @@ -50,7 +50,7 @@ export class SchedulingService { } } } - await this.delay(1); + await this.delay(0); } } } diff --git a/mediarepo-ui/src/app/services/state/state.service.ts b/mediarepo-ui/src/app/services/state/state.service.ts index 3d2a0f7..36b2f32 100644 --- a/mediarepo-ui/src/app/services/state/state.service.ts +++ b/mediarepo-ui/src/app/services/state/state.service.ts @@ -1,11 +1,15 @@ import {Injectable} from "@angular/core"; import {BehaviorSubject, Subscription} from "rxjs"; -import {AppState} from "../../models/AppState"; +import {AppState} from "../../models/state/AppState"; import {FileService} from "../file/file.service"; import {RepositoryService} from "../repository/repository.service"; -import {TabState} from "../../models/TabState"; +import {FilesTabState} from "../../models/state/FilesTabState"; import {debounceTime} from "rxjs/operators"; import {MediarepoApi} from "../../../api/Api"; +import {StateServices} from "../../models/state/StateServices"; +import {ImportTabState} from "../../models/state/ImportTabState"; +import {TabState} from "../../models/state/TabState"; +import {TabCategory} from "../../models/state/TabCategory"; @Injectable({ providedIn: "root" @@ -19,12 +23,12 @@ export class StateService { private stateChange = new BehaviorSubject(undefined); constructor(private fileService: FileService, private repoService: RepositoryService) { - this.state = new BehaviorSubject(new AppState(fileService)); + this.state = new BehaviorSubject(new AppState(this.getServices())); this.repoService.selectedRepository.subscribe(async (repo) => { if (repo && (!this.state.value.repoName || this.state.value.repoName !== repo.name)) { await this.loadState(); } else { - const state = new AppState(this.fileService); + const state = new AppState(this.getServices()); this.subscribeToState(state); this.state.next(state); } @@ -43,13 +47,13 @@ export class StateService { if (stateString) { try { - state = AppState.deserializeJson(stateString, this.fileService); + state = AppState.deserializeJson(stateString, this.getServices()); } catch (err) { console.error("could not deserialize malformed state: ", err); - state = new AppState(this.fileService); + state = new AppState(this.getServices()); } } else { - state = new AppState(this.fileService); + state = new AppState(this.getServices()); } let selectedRepo = this.repoService.selectedRepository.value; if (selectedRepo) { @@ -75,17 +79,38 @@ export class StateService { tabs.forEach((tab) => this.subscribeToTab(tab)); this.stateChange.next(); }); + state.selectedTab.subscribe(() => this.stateChange.next()); } private subscribeToTab(tab: TabState) { + if (tab.category === TabCategory.Files) { + this.subscribeToFilesTab(tab as FilesTabState); + } else if (tab.category === TabCategory.Import) { + this.subscribeToImportTab(tab as ImportTabState); + } + } + + private subscribeToImportTab(tab: ImportTabState) { + this.tabSubscriptions.push(tab.mode + .subscribe(() => this.stateChange.next())); + } + + private subscribeToFilesTab(tab: FilesTabState) { this.tabSubscriptions.push(tab.filters .subscribe(() => this.stateChange.next())); + this.tabSubscriptions.push(tab.files + .subscribe(() => this.stateChange.next())); this.tabSubscriptions.push(tab.sortingPreset .subscribe(() => this.stateChange.next())); this.tabSubscriptions.push( tab.selectedCD.subscribe(() => this.stateChange.next())); this.tabSubscriptions.push( tab.mode.subscribe(() => this.stateChange.next())); - this.tabSubscriptions.push(tab.files.subscribe(() => this.stateChange.next())); + this.tabSubscriptions.push(tab.mode + .subscribe(() => this.stateChange.next())); + } + + private getServices(): StateServices { + return new StateServices(this.fileService); } } diff --git a/mediarepo-ui/src/app/utils/tag-utils.ts b/mediarepo-ui/src/app/utils/tag-utils.ts new file mode 100644 index 0000000..bfb74f7 --- /dev/null +++ b/mediarepo-ui/src/app/utils/tag-utils.ts @@ -0,0 +1,18 @@ +/** + * Normalizes the tag by removing whitespaces and enforcing lowercase + * @param {string} tag + * @returns {string} + * @private + */ +export function normalizeTag(tag: string): string { + let normalizedTag = tag.trim().toLowerCase(); + let parts = normalizedTag.split(":"); + + if (parts.length > 1) { + const namespace = parts.shift()!.trim(); + const name = parts.join(":").trim(); + return namespace + ":" + name; + } else { + return normalizedTag; + } +} diff --git a/mediarepo-ui/src/colors.scss b/mediarepo-ui/src/colors.scss index e8403cc..ad1de7c 100644 --- a/mediarepo-ui/src/colors.scss +++ b/mediarepo-ui/src/colors.scss @@ -12,6 +12,7 @@ $primary-darker-20: darken($primary, 20%); $primary-darker-30: darken($primary, 30%); $accent: mat.get-color-from-palette($accent-pallette, 'text'); +$accent-darker-10: darken($accent, 10%); $accent-lighter-10: lighten($accent, 10%); $warn: mat.get-color-from-palette($warn-palette); @@ -21,9 +22,17 @@ $warn-chill: #fcd349; $text: #FFF; $text-darker-10: darken($text, 10%); -$background: #424242; -$background-lighter-05: lighten($background, 4%); +$background: darken(#373a46, 10%); +$background-darker-05: darken($background, 5%); +$background-darker-10: darken($background, 10%); +$background-lighter-05: lighten($background, 5%); $background-lighter-10: lighten($background, 10%); +$background-lighter-15: lighten($background, 15%); // specifics $tag-namespace: $accent-lighter-10; + + +// fonts +$typography-config: mat.get-typography-config($theme); +$font-family: mat.font-family($typography-config); diff --git a/mediarepo-ui/src/material-theme-correction.scss b/mediarepo-ui/src/material-theme-correction.scss new file mode 100644 index 0000000..0de1762 --- /dev/null +++ b/mediarepo-ui/src/material-theme-correction.scss @@ -0,0 +1,78 @@ +@import "colors"; + +.mat-form-field.mat-focused .mat-form-field-label { + color: $primary-lighter-30; +} + +.mat-input-element { + caret-color: $primary-lighter-20; +} + +.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple) { + background: rgba(255, 255, 255, 0.05); + color: $primary-lighter-20; +} + +.mat-dialog-container { + background: $background-lighter-05; +} + +.mat-drawer { + background: $background !important; +} + +.mat-flat-button, .mat-raised-button, .mat-fab, .mat-mini-fab { + background: $background; +} + +.mat-form-field-flex { + background: $background-lighter-05; +} + +.mat-form-field-appearance-fill .mat-form-field-flex { + background: $background-lighter-05; +} + +.mat-autocomplete-panel, mat-option, .mat-menu-panel { + background: $background-lighter-05; +} + +button .mat-flat-button { + background: $background-lighter-05; +} + +mat-option { + &.mat-selected { + background: $background-lighter-10 !important; + } + + &:hover { + background: darken($background-lighter-10, 1%) !important; + } +} + +mat-toolbar.mat-toolbar { + background: $background-darker-05; +} + +.mat-card { + background: $background-lighter-10; +} + +// scrollbar + +::-webkit-scrollbar { + width: 15px; + height: 15px; + background: $background-darker-05; +} + +::-webkit-scrollbar-thumb { + background: $primary-darker-10; + border-radius: 1px; +} + +::-webkit-scrollbar-thumb:hover { + background: $primary; + border-radius: 5px; +} diff --git a/mediarepo-ui/src/styles.scss b/mediarepo-ui/src/styles.scss index 9dab08d..1687cac 100644 --- a/mediarepo-ui/src/styles.scss +++ b/mediarepo-ui/src/styles.scss @@ -1,14 +1,11 @@ @use 'sass:map'; @use "@angular/material" as mat; -@use 'src/app/app.component-theme' as app; -@use 'app/components/shared/file/file-card/file-card.component-theme' as file-card; -@use 'app/components/shared/sidebar/file-search/file-search.component-theme' as file-search; @include mat.core(); $theme: mat.define-dark-theme(( color: ( - primary: mat.define-palette(mat.$purple-palette, 700, 500, 800), + primary: mat.define-palette(mat.$purple-palette, 500, 300, 800), accent: mat.define-palette(mat.$green-palette, A200, A100, A400), warn: mat.define-palette(mat.$red-palette), background: mat.define-palette(mat.$blue-grey-palette) @@ -18,28 +15,13 @@ $theme: mat.define-dark-theme(( ) )); + $color-config: mat.get-color-config($theme); $primary-palette: map.get($color-config, 'primary'); $accent-pallette: map.get($color-config, 'accent'); $background-pallette: map.get($color-config, 'background'); $warn-palette: map.get($color-config, 'warn'); -::-webkit-scrollbar { - width: 15px; - height: 15px; - background: #272727; -} - -::-webkit-scrollbar-thumb { - background: mat.get-color-from-palette($primary-palette, 'darker'); - border-radius: 1px; -} - -::-webkit-scrollbar-thumb:hover { - background: mat.get-color-from-palette($primary-palette); -} @include mat.all-component-themes($theme); -@include app.theme($theme); -@include file-card.theme($theme); -@include file-search.theme($theme); + diff --git a/mediarepo-ui/tsconfig.json b/mediarepo-ui/tsconfig.json index 6df8283..c28ea5a 100644 --- a/mediarepo-ui/tsconfig.json +++ b/mediarepo-ui/tsconfig.json @@ -1,30 +1,30 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "compileOnSave": false, - "compilerOptions": { - "baseUrl": "./", - "outDir": "./dist/out-tsc", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "sourceMap": true, - "declaration": false, - "downlevelIteration": true, - "experimentalDecorators": true, - "moduleResolution": "node", - "importHelpers": true, - "target": "es2017", - "module": "es2020", - "lib": [ - "es2018", - "dom" - ] - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2020", + "module": "ESNext", + "lib": [ + "ES2020", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } } diff --git a/mediarepo-ui/yarn.lock b/mediarepo-ui/yarn.lock index 0c78084..bcafdd6 100644 --- a/mediarepo-ui/yarn.lock +++ b/mediarepo-ui/yarn.lock @@ -10,23 +10,30 @@ "@jridgewell/resolve-uri" "1.0.0" sourcemap-codec "1.4.8" -"@angular-devkit/architect@0.1301.3": - version "0.1301.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1301.3.tgz#197f92c984adf22776798ce568e64396e464a03d" - integrity sha512-fFSevgYGZHCybYoyTkZ9b1YCSthBmoi77alwWjqMhYXUNXx7yx50zJZ6Ur2v3YpctVjU6eoGc5FDFyVHwXT0Iw== +"@ampproject/remapping@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.0.tgz#72becdf17ee44b2d1ac5651fb12f1952c336fe23" + integrity sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@angular-devkit/architect@0.1301.4": + version "0.1301.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1301.4.tgz#2fc51bcae0dcb581c8be401e2fde7bbd10b43076" + integrity sha512-p6G8CEMnE+gYwxRyEttj3QGsuNJ3Kusi7iwBIzWyf2RpJSdGzXdwUEiRGg6iS0YHFr06/ZFfAWfnM2DQvNm4TA== dependencies: - "@angular-devkit/core" "13.1.3" + "@angular-devkit/core" "13.1.4" rxjs "6.6.7" "@angular-devkit/build-angular@~13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-13.1.3.tgz#c04cef8a2d405cb66332b674d204a2717b6807f6" - integrity sha512-C5Qv8aGmpGbETG4Mawly/5LnkRwfJAzANL5BtYJn8ZaDlZKCkhvAaRXHpm4Mdqg5idACAT8hgYqPQvqyEBaVDA== + version "13.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-13.1.4.tgz#942023fca240b0f5753dcf65bb67e57e4779bf86" + integrity sha512-MTvlUCb02J4ODXDsnit4N0PR9PkpKeSYpTPueaSBuWTBeP3dvMPZQabvb3C5QT/5yUzBiXQZq11QYx3Gui4StA== dependencies: "@ampproject/remapping" "1.0.2" - "@angular-devkit/architect" "0.1301.3" - "@angular-devkit/build-webpack" "0.1301.3" - "@angular-devkit/core" "13.1.3" + "@angular-devkit/architect" "0.1301.4" + "@angular-devkit/build-webpack" "0.1301.4" + "@angular-devkit/core" "13.1.4" "@babel/core" "7.16.0" "@babel/generator" "7.16.0" "@babel/helper-annotate-as-pure" "7.16.0" @@ -37,7 +44,7 @@ "@babel/runtime" "7.16.3" "@babel/template" "7.16.0" "@discoveryjs/json-ext" "0.5.6" - "@ngtools/webpack" "13.1.3" + "@ngtools/webpack" "13.1.4" ansi-colors "4.1.1" babel-loader "8.2.3" babel-plugin-istanbul "6.1.1" @@ -67,7 +74,7 @@ postcss "8.4.4" postcss-import "14.0.2" postcss-loader "6.2.1" - postcss-preset-env "6.7.0" + postcss-preset-env "7.2.3" regenerator-runtime "0.13.9" resolve-url-loader "4.0.0" rxjs "6.6.7" @@ -90,18 +97,18 @@ optionalDependencies: esbuild "0.14.11" -"@angular-devkit/build-webpack@0.1301.3": - version "0.1301.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1301.3.tgz#4f8f9fd9e09992aaf904c4457f268b203c19b45d" - integrity sha512-FFwKdhq5n0lrqkiJRZoWKy21gERtvupkk0BpIVPTbRqyiqB2htiGM995uBBjpeDngytDLx+BwPFipVfQ+WIi9w== +"@angular-devkit/build-webpack@0.1301.4": + version "0.1301.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1301.4.tgz#7dd16ec7fb26c5e177ad26a6f485faf4393774ef" + integrity sha512-IcC3Y5WhreIV0uT90ITqJVgRqFjGwH72hftwLxkslaX+FJDcL36mhsNdyN66BJiuX7R85xUxHq3PEb9cZrllJA== dependencies: - "@angular-devkit/architect" "0.1301.3" + "@angular-devkit/architect" "0.1301.4" rxjs "6.6.7" -"@angular-devkit/core@13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-13.1.3.tgz#d1f8a6b4ad4326732a160a7549fccca1369fd108" - integrity sha512-o14jGDk4h14dVYYQafOn+2rq9CDmDMbDV6logqKYCLzTDRlK8gccDnqJM/QKAlfWCzbllZqcHDmg6FyoRLO9RQ== +"@angular-devkit/core@13.1.4": + version "13.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-13.1.4.tgz#b5b6ddd674ae351f83beff2e4a0d702096bdfd47" + integrity sha512-225Gjy4iVxh5Jo9njJnaG75M/Dt95UW+dEPCGWKV5E/++7UUlXlo9sNWq8x2vJm2nhtsPkpnXNOt4pW1mIDwqQ== dependencies: ajv "8.8.2" ajv-formats "2.1.1" @@ -110,12 +117,12 @@ rxjs "6.6.7" source-map "0.7.3" -"@angular-devkit/schematics@13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-13.1.3.tgz#2328f9cf63d6f556392d96b73af794fc52bfc87f" - integrity sha512-TvjThB/pFXNFM0j0WX5yg0L2/3xNsqawQuWhkDJ05MBDEnSxbgv5hmOzNL8SNIEMgP0VbSTHtSg5kZvmNiH7vg== +"@angular-devkit/schematics@13.1.4": + version "13.1.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-13.1.4.tgz#e8ed817887aa51268dec27d8d6188e2f3f10742a" + integrity sha512-yBa7IeC4cLZ7s137NAQD+sMB5c6SI6UJ6xYxl6J/CvV2RLGOZZA93i4GuRALi5s82eLi1fH+HEL/gvf3JQynzQ== dependencies: - "@angular-devkit/core" "13.1.3" + "@angular-devkit/core" "13.1.4" jsonc-parser "3.0.0" magic-string "0.25.7" ora "5.4.1" @@ -179,30 +186,30 @@ "@typescript-eslint/experimental-utils" "5.3.0" "@angular/animations@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-13.1.2.tgz#fdf0776eaf053b14a4118c682a62f24e4192609a" - integrity sha512-k1eQ8YZq3eelLhJDQjkRCt/4MXxwK2TFeGdtcYJF0G7vFOppE8hlI4PT7Bvmk08lTqvgiqtTI3ZaYmIINLfUMg== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-13.1.3.tgz#2da6ad99602bfb450624a7499d6f81366c3a4519" + integrity sha512-OwsVQsNHubIgRcxnjti4CU3QJnqd7Z2b+2iu3M349Oxyqxz4DNCqKXalDuJZt/b0yNfirvYO3kCgBfj4PF43QQ== dependencies: tslib "^2.3.0" "@angular/cdk@^13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-13.1.2.tgz#aaa1b577d1b8101d3d59f4da9a1ea51b7f7a5191" - integrity sha512-xORyqvfM0MueJpxHxVi3CR/X/f1RPKr45vt7NV6/x91OTnh2ukwxg++dAGuA6M5gUAHcVAcaBrfju4GQlU9hmg== + version "13.2.1" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-13.2.1.tgz#7b9b4ee7423a62a9a5ec62544d13fd1ff7ad15f7" + integrity sha512-AjEn4Mk2ow2i8pw0T9F/C/bKFrnUqzlvOGfFkoMgZHp5r3yhDb5DbVRS1/fGScAbY8Pzln49r1maKdrE8DGUbg== dependencies: tslib "^2.3.0" optionalDependencies: parse5 "^5.0.0" "@angular/cli@~13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-13.1.3.tgz#d143f30ee67481cc315e0d18fecb076101dfa280" - integrity sha512-Ju/A8LFnfcv1PC665a5FiIQx9SXqB+3yWYFXPIiVkkRcye95gpfsbV48WW7QV35gzIwbR1m3H907Zg6ptiNv0A== - dependencies: - "@angular-devkit/architect" "0.1301.3" - "@angular-devkit/core" "13.1.3" - "@angular-devkit/schematics" "13.1.3" - "@schematics/angular" "13.1.3" + version "13.1.4" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-13.1.4.tgz#34e6e87d1c6950408167c41293cf2cd5d1e00a2e" + integrity sha512-PP9xpvDDCHhLTIZjewQQzzf+JbpF2s5mXTW2AgIL/E53ukaVvXwwjFMt9dQvECwut/LDpThoc3OfqcGrmwtqnA== + dependencies: + "@angular-devkit/architect" "0.1301.4" + "@angular-devkit/core" "13.1.4" + "@angular-devkit/schematics" "13.1.4" + "@schematics/angular" "13.1.4" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" debug "4.3.3" @@ -220,16 +227,16 @@ uuid "8.3.2" "@angular/common@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-13.1.2.tgz#6a4abe30b1cc42702452bfd2214e482675f5d889" - integrity sha512-/8RWYQkZ1KPNvu2FANJM44wXlOMjMyxZVOEIn3llMRgxV2iiYtmluAOJNafTAbKedAuD6wiSpbi++QbioqCyyA== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-13.1.3.tgz#4c80f45cfd00a17543559c5fbebe0a7a7cf403ed" + integrity sha512-8qf5syeXUogf3+GSu6IRJjrk46UKh9L0QuLx+OSIl/df0y1ewx7e28q3BAUEEnOnKrLzpPNxWs2iwModc4KYfg== dependencies: tslib "^2.3.0" "@angular/compiler-cli@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-13.1.2.tgz#f9adde80bd9d0c3d90d8758c9803537373259053" - integrity sha512-yqM6RLcYtfwIuqBQ7eS7WdksBYY7Dh9sP4rElgLiEhDGIPQf6YE5zeuRThGq5pQ2fvHbNflw8QmTHu/18Y1u/g== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-13.1.3.tgz#0269370350e928f22f3150523f95bc490a1e7a7a" + integrity sha512-ALURaJATc54DzPuiZBvALf/alEp1wr7Hjmw4FuMn2cU7p8lwKkra1Dz5dAZOxh7jAcD1GJfrK/+Sb7A3cuuKjQ== dependencies: "@babel/core" "^7.8.6" canonical-path "1.0.0" @@ -244,58 +251,58 @@ yargs "^17.2.1" "@angular/compiler@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-13.1.2.tgz#86afbe282d0ff407fd8aeb66a79a804f40e7efa4" - integrity sha512-xbM3eClhUIHEFR0Et1bVC18Q7+kJx+hNNWWQl63RNYYBxTZnZpXA3mYi6IcEasy7BHkobVW+5teqlibFQY4gfQ== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-13.1.3.tgz#fc33b06046599ecc943f55049e0a121d5ab46d4f" + integrity sha512-dbHs/Oa+Dn+7i0jKtlVDE0lD0DaUC+lVzAcTK/zS37LrckrTMn1CA+z9bZ4gpHig9RU0wgV3YORxv0wokyiB8A== dependencies: tslib "^2.3.0" "@angular/core@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-13.1.2.tgz#793b97d0b7339d5b405f39dd5d021b4b78fcf256" - integrity sha512-dsb90lUf8BELzdg7MgSMfPc36xzZKsDggOimfXhIvmctgc+H71Zo07KYTy5JVqsscLdT+A/KBvtU1bKk4P+Rfg== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-13.1.3.tgz#4afd71f674f9ead1aada81315f84846cdba10fa4" + integrity sha512-rvCnIAonRx7VnH2Mv9lQR+UYdlFQQetZCjPw8QOswOspEpHpEPDrp1HxDIqJnHxNqW0n8J3Zev/VgQYr0481UA== dependencies: tslib "^2.3.0" "@angular/flex-layout@^13.0.0-beta.36": - version "13.0.0-beta.36" - resolved "https://registry.yarnpkg.com/@angular/flex-layout/-/flex-layout-13.0.0-beta.36.tgz#0e91e6837b767841b579f8a5be66667255e30484" - integrity sha512-JLC3C1oEKVu9lLyottvHbfyCf/pOPzjXfFO3qOPBbWyVqxuQkfkd2NILZZh4DHsKYbBxIZ01vnfQHCV8NdaZ3w== + version "13.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@angular/flex-layout/-/flex-layout-13.0.0-beta.38.tgz#b0993a255ba51d2cfd16537ba8a8d88c3adf6587" + integrity sha512-kcWb7CcoHbvw7fjo/knizWVmSSmvaTnr8v1ML6zOdxu1PK9UPPOcOS8RTm6fy61zoC2LABivP1/6Z2jF5XfpdQ== dependencies: tslib "^2.3.0" "@angular/forms@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-13.1.2.tgz#f72d7f84b78844a1606cd4226c2a3a1eb1de56b5" - integrity sha512-r5I5cPngk2Erxe/OEL9Hl1j1VcNSAAyVzh7KmtOP8z7RZYCd0MeRISKrmA5CGn5Dh7A5POFLoOpBatmvnc4Z/A== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-13.1.3.tgz#4b31d1208e2b191766efbbe1a502193e28e89240" + integrity sha512-c4N9zZSILyEbomY2CJo1WAMxiHu/qlycvzxKH5NFS2P2+fieORlbKUJ2p1CbYqcIxVnLYRSdWH8f1JpoaG0ETw== dependencies: tslib "^2.3.0" "@angular/material@^13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-13.1.2.tgz#497e9b34f4672ce207bb1198a823cda1f1d416ef" - integrity sha512-M7eDgTMCZ/naoiS6Z5nj3N/sNUFc+CGPHX4yb563RuknqN7huDCvdyxA6KnhYLZsVlNCPh5ZrEr6H8ZiYJWcpg== + version "13.2.1" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-13.2.1.tgz#a0511d74c183ae9b02ead8d1443d5059182f384f" + integrity sha512-8pJuDsUqWDJemjog/18qrQf72K/BiptDCEY3PfvBK1Wkya6qUKfHKI/iCsToJL56vZ4N07hQHBe/KmYusZtHrQ== dependencies: tslib "^2.3.0" "@angular/platform-browser-dynamic@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.1.2.tgz#2d381503862be7a9d5fd74a27c1f8cf10d9b086e" - integrity sha512-gABOn8DxGai56WmIt5o+eXtduabiq4Mlprg+6+dv+2PvWV871pLvswV9EGUSgwKXvbhBlDZDuNFU5LgvNDuGFg== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.1.3.tgz#08cbe321e5f39636a08eb77606ff496df478a21e" + integrity sha512-vEWyJ+2gkwh2N6KOJfxUNSdSO51ROlzCqqzCfHrPYQrlOFUfKsYKA1uoiB5UGfFEU0HBtIRWn6xoUy3wzVOZbw== dependencies: tslib "^2.3.0" "@angular/platform-browser@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-13.1.2.tgz#6b24c26cc01733f933a3c15288989259f83e8f46" - integrity sha512-yBUWtYJHr/1LuK3/YRRav2O82i6RHVPtRoAlZHoeTlh2CYA4u1m3JHq9XBrxIxSXexBX69pMrZENW1xskwKRTQ== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-13.1.3.tgz#69d90b10e89e11f14f5798d1b6fd788255a6114e" + integrity sha512-mnWjdr9UTNZvGk8jPI6O9FIhun8Q/0ghy3dg3I9AfRzEG4vPiIZW1ICksTiB+jV9etzhKpidtmg71bwgeXax1A== dependencies: tslib "^2.3.0" "@angular/router@~13.1.2": - version "13.1.2" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-13.1.2.tgz#69146055473b9f5b8f9ba9b4de3a0740778ea174" - integrity sha512-5S0De6SdlbERoX9FwOBiTWxINchW7nTPUIH/tdanOqq12cqp6/7NigOr3BZDSvUNIh/6Is+pSQTKGAbhxejN2w== + version "13.1.3" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-13.1.3.tgz#2330254febabce55061236f1761a03aae9a9418f" + integrity sha512-L86kARlc5UNi5KeI0O8PO7wFbTzjEI8ouz+z+aNmCnMUUNX0rbvbuXiPdDvLc71nKZznsPCl2IuO8ojyHrSPsQ== dependencies: tslib "^2.3.0" @@ -312,9 +319,9 @@ "@babel/highlight" "^7.16.7" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" - integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== "@babel/core@7.16.0": version "7.16.0" @@ -338,25 +345,25 @@ source-map "^0.5.0" "@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.6": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" - integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.0.tgz#16b8772b0a567f215839f689c5ded6bb20e864d5" + integrity sha512-x/5Ea+RO5MvF9ize5DeVICJoVrNv0Mi2RnIABrZEKYvPEpldXwauPkgvYA17cKa6WpU3LoYvYbuEMFtSNFsarA== dependencies: + "@ampproject/remapping" "^2.0.0" "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.7" + "@babel/generator" "^7.17.0" "@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-module-transforms" "^7.16.7" - "@babel/helpers" "^7.16.7" - "@babel/parser" "^7.16.7" + "@babel/helpers" "^7.17.0" + "@babel/parser" "^7.17.0" "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" "@babel/generator@7.16.0": version "7.16.0" @@ -367,12 +374,12 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.16.0", "@babel/generator@^7.16.7", "@babel/generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" - integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== +"@babel/generator@^7.16.0", "@babel/generator@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== dependencies: - "@babel/types" "^7.16.8" + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -408,10 +415,10 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz#9c5b34b53a01f2097daf10678d65135c1b9f84ba" - integrity sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw== +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": + version "7.17.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" + integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7" @@ -422,17 +429,17 @@ "@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" - integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^4.7.1" + regexpu-core "^5.0.1" -"@babel/helper-define-polyfill-provider@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" - integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== +"@babel/helper-define-polyfill-provider@^0.3.0", "@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -581,28 +588,28 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helpers@^7.16.0", "@babel/helpers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" - integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== +"@babel/helpers@^7.16.0", "@babel/helpers@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.0.tgz#79cdf6c66a579f3a7b5e739371bc63ca0306886b" + integrity sha512-Xe/9NFxjPwELUvW2dsukcMZIp6XwPSbI4ojFBJuX5ramHuVE22SVcZIwqzdWo5uCgeTXW8qV97lMvSOjq+1+nQ== dependencies: "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" "@babel/highlight@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" - integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.7", "@babel/parser@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" - integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== +"@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.7", "@babel/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": version "7.16.7" @@ -732,11 +739,11 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-proposal-private-methods@^7.16.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz#e418e3aa6f86edd6d327ce84eff188e479f571e0" - integrity sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw== + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.10" "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-proposal-private-property-in-object@^7.16.0": @@ -1218,9 +1225,9 @@ esutils "^2.0.2" "@babel/runtime-corejs3@^7.10.2": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.16.8.tgz#ea533d96eda6fdc76b1812248e9fbd0c11d4a1a7" - integrity sha512-3fKhuICS1lMz0plI5ktOE/yEtBRMVxplzRkdn6mJQ197XiY0JnrzYV0+Mxozq3JZ8SBV9Ecurmw1XsGbwOf+Sg== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.0.tgz#9de2f75b3ca4b68628c01bd76410b64faa4644f7" + integrity sha512-qeydncU80ravKzovVncW3EYaC1ji3GpntdPgNcJy9g7hHSY6KX+ne1cbV3ov7Zzm4F1z0+QreZPCuw1ynkmYNg== dependencies: core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" @@ -1233,9 +1240,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.10.2", "@babel/runtime@^7.8.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" - integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.0.tgz#b8d142fc0f7664fb3d9b5833fd40dcbab89276c0" + integrity sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ== dependencies: regenerator-runtime "^0.13.4" @@ -1257,35 +1264,30 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c" - integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ== +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== dependencies: "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.0" "@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-function-name" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.4.4": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" - integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== +"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.4.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@csstools/convert-colors@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" - integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== - "@discoveryjs/json-ext@0.5.6": version "0.5.6" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" @@ -1312,9 +1314,9 @@ integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== "@humanwhocodes/config-array@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" - integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== + version "0.9.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.3.tgz#f2564c744b387775b436418491f15fce6601f63e" + integrity sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -1346,31 +1348,49 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-1.0.0.tgz#3fdf5798f0b49e90155896f6291df186eac06c83" integrity sha512-9oLAnygRMi8Q5QkYEU4XWK04B+nuoXoxjRvRxgjuChkLZFBja0YPSgdZ7dZtwhncLBcQe/I/E+fLuk5qxcYVJA== +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72" + integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.10" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186" + integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.2.tgz#e051581782a770c30ba219634f2019241c5d3cde" + integrity sha512-9KzzH4kMjA2XmBRHfqG2/Vtl7s92l6uNDd0wW7frDE+EUvQFGqNXhWp0UGJjSkt3v2AYjzOZn1QO9XaTNJIt1Q== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@ng-icons/core@^13.2.1": - version "13.2.1" - resolved "https://registry.yarnpkg.com/@ng-icons/core/-/core-13.2.1.tgz#46d1d97d3d479da2fd2ca3b58978715f6b261338" - integrity sha512-4wI60pGxD9ul9kEipY8Ph0cza6d71xAJj6eE1fqFDtTQ4DDUfSSGFbB8grxs9qUec5B9QCLk8QoLaAWEzyDn8Q== + version "13.3.0" + resolved "https://registry.yarnpkg.com/@ng-icons/core/-/core-13.3.0.tgz#30e2bb8ccf0a433f08f8ee05d287924fb9a944d1" + integrity sha512-nOdkATobPI5BOhqiIYz2+FNyhKqgShzqNJcx8ZRiJqhYJ2VrKSuE8D51VAdQVCDC5WFKAa8h7Nnmj+J7S4270Q== dependencies: tslib "^2.2.0" "@ng-icons/feather-icons@^13.2.1": - version "13.2.1" - resolved "https://registry.yarnpkg.com/@ng-icons/feather-icons/-/feather-icons-13.2.1.tgz#1a937711f0b11aa505914a84abec685dfebf1bf6" - integrity sha512-Uvassb3YS1bkQyrkHrUAimf5G7sAC9EzjZUSEbb23zsTYqp8R2Z4rUcJJkhzC/xZecKLhRqldQlKFsRVoo+Iug== + version "13.3.0" + resolved "https://registry.yarnpkg.com/@ng-icons/feather-icons/-/feather-icons-13.3.0.tgz#c2bcd860fbc610d3c8139e545e50b3524dba779c" + integrity sha512-CJNSiy3yhciyx1pTElIQcTsQyRuD3+tOWBMCDqzf9IlnqOgTsOVB/UH4ZtmVMxOleGdPQffwemAxYg6XVN4PqA== dependencies: tslib "^2.2.0" "@ng-icons/material-icons@^13.2.1": - version "13.2.1" - resolved "https://registry.yarnpkg.com/@ng-icons/material-icons/-/material-icons-13.2.1.tgz#4dcfd26f60f6c0c23fff28abc7f6c66931fb264e" - integrity sha512-YvIrLD6n/BuJTPRyNh3K9WBCid5MfstbFgkhGUeVOySlNriVMClusCL5KEwxq4xtFk7Q7pYkT8sIKd3x8E3SDA== + version "13.3.0" + resolved "https://registry.yarnpkg.com/@ng-icons/material-icons/-/material-icons-13.3.0.tgz#dc2ac98bcd9216b4df97a984c94ff5b8b5c6f493" + integrity sha512-AQaz5Gmb2w8jE1sviUn/Ia79+xpbfbMN3KwveEUHshCw2Up2c0PhdiA/wP+5NuTMb6AXLn2qvnuja9BNmWu/UA== dependencies: tslib "^2.2.0" -"@ngtools/webpack@13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-13.1.3.tgz#f3e516da2b2a352db9d723e8cebbe15b526de14c" - integrity sha512-6Pf52IbChm/dFuegfv0smeBTW2moi0Gdkyjgk/7VWqE6hN35m+YGrCh+XnPp1POJwOKxhAByhV9zs6NWxrK1vA== +"@ngtools/webpack@13.1.4": + version "13.1.4" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-13.1.4.tgz#359c9078af281413cf9cabd0af06b3fca4ddbf7e" + integrity sha512-s8gzjG2nYHawFhlkHMkQWYrocHkBI1nF6T9K/oCSTIsq6kvTv//Ahno2VdBSgVq8uMnpv1TymvX0nFC4Dgn1HA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1453,16 +1473,15 @@ node-gyp "^8.2.0" read-package-json-fast "^2.0.1" -"@nrwl/cli@*", "@nrwl/cli@13.4.5": - version "13.4.5" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-13.4.5.tgz#21937c66d7bc7d2109c5e32b7ed2f1bbf8509979" - integrity sha512-CyiGIBhVd2EEx3+HST5TwOwI6kL8zKvWBMXrHs0jAB9lJIjqdzLdTPYHsfLOcAYsl08l8eySVVCkGr9UG5XSPQ== +"@nrwl/cli@*", "@nrwl/cli@13.7.3": + version "13.7.3" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-13.7.3.tgz#2e5f5ace22db58b3176dd28e2830a59f306be5bb" + integrity sha512-iL10s55Levr2mI/qhKoHuYARYHniS9zlu0+yM6W1kRglJkJpX1KkbGwQ8P6TRImEdz1FlZQqJ/X8qMSH13eOhA== dependencies: - "@nrwl/tao" "13.4.5" + "@nrwl/tao" "13.7.3" chalk "4.1.0" enquirer "~2.3.6" v8-compile-cache "2.3.0" - yargs "15.4.1" yargs-parser "20.0.0" "@nrwl/devkit@13.1.3": @@ -1494,10 +1513,10 @@ tslib "^2.0.0" yargs-parser "20.0.0" -"@nrwl/tao@13.4.5": - version "13.4.5" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-13.4.5.tgz#bb61a1280a10dfca8956af42cb3e60443381b2b3" - integrity sha512-DYVmYDEeJ9zLagU52nVXBdA+0SXrypmydrxFLhEAc79tlForNX3dmjqePhNDq7JqllmD643DiNh0pydgsPzUdQ== +"@nrwl/tao@13.7.3": + version "13.7.3" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-13.7.3.tgz#af4d3c21e7b4e529813a8b40ea11a0769d0305c3" + integrity sha512-D/0lZj/BhY+fkEYfrgtfOFwRCX129rbuFpAKsk52fJkXym5tWdWMrNwMQPtoi+GqSKJSksyvi9wESZuQQ+/jPA== dependencies: chalk "4.1.0" enquirer "~2.3.6" @@ -1505,7 +1524,7 @@ fs-extra "^9.1.0" ignore "^5.0.4" jsonc-parser "3.0.0" - nx "13.4.5" + nx "13.7.3" rxjs "^6.5.4" rxjs-for-await "0.0.2" semver "7.3.4" @@ -1513,13 +1532,13 @@ tslib "^2.3.0" yargs-parser "20.0.0" -"@schematics/angular@13.1.3": - version "13.1.3" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-13.1.3.tgz#c763cdf1a2e0784d5263c23b581bfeb4a4a2f12e" - integrity sha512-IixVWAEtN97N74PCxg3T03Ar/ECjGyJBWKAjKTTCrgNSWhm2mKgIc4RyI6cVCnltfJWIo48fcFhlOx/elShaCg== +"@schematics/angular@13.1.4": + version "13.1.4" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-13.1.4.tgz#8b8c9ad40403c485bae9adeb51649711651189d2" + integrity sha512-P1YsHn1LLAmdpB9X2TBuUgrvEW/KaoBbHr8ifYO8/uQEXyeiIF+So8h/dnegkYkdsr3OwQ2X/j3UF6/+HS0odg== dependencies: - "@angular-devkit/core" "13.1.3" - "@angular-devkit/schematics" "13.1.3" + "@angular-devkit/core" "13.1.4" + "@angular-devkit/schematics" "13.1.4" jsonc-parser "3.0.0" "@sindresorhus/is@^0.14.0": @@ -1533,9 +1552,14 @@ integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== "@sindresorhus/is@^4.0.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.2.1.tgz#b88b5724283db80b507cd612caee9a1947412a20" - integrity sha512-BrzrgtaqEre0qfvI8sMTaEvx+bayuhPmfe2rfeUGPPHYr/PLxCOqkOe4TQTDPb+qcqgNcsAtXV/Ew74mcDIE8w== + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.4.0.tgz#e277e5bdbdf7cb1e20d320f02f5e2ed113cd3185" + integrity sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ== + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== "@szmarczak/http-timer@^1.1.2": version "1.1.2" @@ -1630,14 +1654,19 @@ "@types/estree" "*" "@types/eslint@*": - version "8.2.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.2.tgz#b64dbdb64b1957cfc8a698c68297fcf8983e94c7" - integrity sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A== + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.50": +"@types/estree@*": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/estree@^0.0.50": version "0.0.50" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== @@ -1652,7 +1681,7 @@ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== -"@types/http-proxy@^1.17.5": +"@types/http-proxy@^1.17.8": version "1.17.8" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== @@ -1677,14 +1706,14 @@ "@types/node" "*" "@types/node@*", "@types/node@>=10.0.0": - version "17.0.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" - integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== + version "17.0.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.15.tgz#97779282c09c09577120a2162e71d8380003590a" + integrity sha512-zWt4SDDv1S9WRBNxLFxFRHxdD9tvH8f5/kg5/IaLFdnSNXsDY4eL3Q3XXN+VxUnWIhyVFDwcsmAprvwXoM/ClA== "@types/node@^16.11.19": - version "16.11.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.19.tgz#1afa165146997b8286b6eabcb1c2d50729055169" - integrity sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng== + version "16.11.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.22.tgz#e704150225bfc4195f8ce68a7ac8da02b753549a" + integrity sha512-DYNtJWauMQ9RNpesl4aVothr97/tIJM8HbyOXJ0AYT1Z2bEjLHyfjOBPAQQVMLf8h3kSShYfNk8Wnto8B2zHUA== "@types/parse-json@^4.0.0": version "4.0.0" @@ -1743,15 +1772,23 @@ eslint-utils "^3.0.0" "@typescript-eslint/parser@^5.9.1": - version "5.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.9.1.tgz#b114011010a87e17b3265ca715e16c76a9834cef" - integrity sha512-PLYO0AmwD6s6n0ZQB5kqPgfvh73p0+VqopQQLuNfi7Lm0EpfKyDalchpVwkE+81k5HeiRrTV/9w1aNHzjD7C4g== + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.2.tgz#b6076d27cc5499ce3f2c625f5ccde946ecb7db9a" + integrity sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg== dependencies: - "@typescript-eslint/scope-manager" "5.9.1" - "@typescript-eslint/types" "5.9.1" - "@typescript-eslint/typescript-estree" "5.9.1" + "@typescript-eslint/scope-manager" "5.10.2" + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/typescript-estree" "5.10.2" debug "^4.3.2" +"@typescript-eslint/scope-manager@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz#92c0bc935ec00f3d8638cdffb3d0e70c9b879639" + integrity sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw== + dependencies: + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/visitor-keys" "5.10.2" + "@typescript-eslint/scope-manager@5.3.0": version "5.3.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz#97d0ccc7c9158e89e202d5e24ce6ba49052d432e" @@ -1777,6 +1814,11 @@ debug "^4.3.2" tsutils "^3.21.0" +"@typescript-eslint/types@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8" + integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w== + "@typescript-eslint/types@5.3.0": version "5.3.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416" @@ -1787,6 +1829,19 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.9.1.tgz#1bef8f238a2fb32ebc6ff6d75020d9f47a1593c6" integrity sha512-SsWegWudWpkZCwwYcKoDwuAjoZXnM1y2EbEerTHho19Hmm+bQ56QG4L4jrtCu0bI5STaRTvRTZmjprWlTw/5NQ== +"@typescript-eslint/typescript-estree@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7" + integrity sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ== + dependencies: + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/visitor-keys" "5.10.2" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + "@typescript-eslint/typescript-estree@5.3.0": version "5.3.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf" @@ -1813,6 +1868,14 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/visitor-keys@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d" + integrity sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q== + dependencies: + "@typescript-eslint/types" "5.10.2" + eslint-visitor-keys "^3.0.0" + "@typescript-eslint/visitor-keys@5.3.0": version "5.3.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523" @@ -1976,12 +2039,12 @@ abbrev@1: integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-import-assertions@^1.7.6: version "1.8.0" @@ -2049,7 +2112,7 @@ ajv-keywords@^5.0.0: dependencies: fast-deep-equal "^3.1.3" -ajv@8.8.2, ajv@^8.0.0, ajv@^8.8.0: +ajv@8.8.2: version "8.8.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== @@ -2069,6 +2132,16 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-align@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -2240,18 +2313,17 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^9.6.1: - version "9.8.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" - integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== +autoprefixer@^10.4.2: + version "10.4.2" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.2.tgz#25e1df09a31a9fba5c40b578936b90d35c9d4d3b" + integrity sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ== dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" + browserslist "^4.19.1" + caniuse-lite "^1.0.30001297" + fraction.js "^4.1.2" normalize-range "^0.1.2" - num2fraction "^1.2.2" - picocolors "^0.2.1" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" axobject-query@^2.2.0: version "2.2.0" @@ -2287,12 +2359,12 @@ babel-plugin-istanbul@6.1.1: test-exclude "^6.0.0" babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" - integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== dependencies: "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.0" + "@babel/helper-define-polyfill-provider" "^0.3.1" semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.4.0: @@ -2304,22 +2376,17 @@ babel-plugin-polyfill-corejs3@^0.4.0: core-js-compat "^3.18.0" babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" - integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.0" + "@babel/helper-define-polyfill-provider" "^0.3.1" balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz#87bd13525626db4a9838e00a508c2b73efcf348c" - integrity sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA== - base64-js@^1.2.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -2477,7 +2544,7 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.6.4, browserslist@^4.9.1: +browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.9.1: version "4.19.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== @@ -2638,7 +2705,7 @@ camelcase@^2.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= -camelcase@^5.0.0, camelcase@^5.3.1: +camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== @@ -2648,10 +2715,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286: - version "1.0.30001299" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001299.tgz#d753bf6444ed401eb503cbbe17aa3e1451b5a68c" - integrity sha512-iujN4+x7QzqA2NCSrS5VUy+4gLmRd4xv6vbBBsmfVqTx8bLAD8097euLqQgKxSVLvxjSDcvF1T/i9ocgnUFexw== +caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001297, caniuse-lite@^1.0.30001299: + version "1.0.30001309" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001309.tgz#e0ee78b9bec0704f67304b00ff3c5c0c768a9f62" + integrity sha512-Pl8vfigmBXXq+/yUz1jUwULeq9xhMJznzdc/xwl4WclDAuebcTHVefpz8lE/bMI+UN7TOkSSe7B7RnZd6+dzjA== canonical-path@1.0.0: version "1.0.0" @@ -2710,9 +2777,9 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.1, chokidar@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -2776,15 +2843,6 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -2984,17 +3042,22 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.1, cookie@~0.4.1: +cookie@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + copy-anything@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87" - integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== dependencies: - is-what "^3.12.0" + is-what "^3.14.1" copy-webpack-plugin@10.0.0: version "10.0.0" @@ -3009,17 +3072,17 @@ copy-webpack-plugin@10.0.0: serialize-javascript "^6.0.0" core-js-compat@^3.18.0, core-js-compat@^3.19.1: - version "3.20.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.2.tgz#d1ff6936c7330959b46b2e08b122a8b14e26140b" - integrity sha512-qZEzVQ+5Qh6cROaTPFLNS4lkvQ6mBzE3R6A6EEpssj7Zr2egMHgsy4XapdifqJDGC9CBiNv7s+ejI96rLNQFdg== + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.0.tgz#bcc86aa5a589cee358e7a7fa0a4979d5a76c3885" + integrity sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A== dependencies: browserslist "^4.19.1" semver "7.0.0" core-js-pure@^3.20.2: - version "3.20.2" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.2.tgz#5d263565f0e34ceeeccdc4422fae3e84ca6b8c0f" - integrity sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg== + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.0.tgz#819adc8dfb808205ce25b51d50591becd615db7e" + integrity sha512-VaJUunCZLnxuDbo1rNOzwbet9E1K9joiXS5+DQMPtgxd24wfsZbJZMMfQLGYMlCUvSxLfsRUUhoOR2x28mFfeg== core-js@3.19.3: version "3.19.3" @@ -3103,20 +3166,19 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-blank-pseudo@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" - integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== +css-blank-pseudo@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== dependencies: - postcss "^7.0.5" + postcss-selector-parser "^6.0.9" -css-has-pseudo@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" - integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== +css-has-pseudo@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== dependencies: - postcss "^7.0.6" - postcss-selector-parser "^5.0.0-rc.4" + postcss-selector-parser "^6.0.9" css-loader@6.5.1: version "6.5.1" @@ -3132,12 +3194,10 @@ css-loader@6.5.1: postcss-value-parser "^4.1.0" semver "^7.3.5" -css-prefers-color-scheme@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" - integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== - dependencies: - postcss "^7.0.5" +css-prefers-color-scheme@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== css-select@^4.2.0: version "4.2.1" @@ -3164,15 +3224,10 @@ css@^3.0.0: source-map "^0.6.1" source-map-resolve "^0.6.0" -cssdb@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" - integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== +cssdb@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-5.1.0.tgz#ec728d5f5c0811debd0820cbebda505d43003400" + integrity sha512-/vqjXhv1x9eGkE/zO6o8ZOI7dgdZbLVLUGyVRbPgk6YipXbW87YzUCcO+Jrmi5bwJlAH6oD+MNeZyRgXea1GZw== cssesc@^3.0.0: version "3.0.0" @@ -3191,15 +3246,10 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -date-format@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" - integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== - -date-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" - integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== +date-format@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873" + integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ== debug@2.6.9: version "2.6.9" @@ -3208,7 +3258,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@~4.3.1, debug@~4.3.2: +debug@4, debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -3229,7 +3279,7 @@ debug@~3.1.0: dependencies: ms "2.0.0" -decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -3554,9 +3604,9 @@ ejs@^3.1.5: jake "^10.6.1" electron-to-chromium@^1.4.17: - version "1.4.46" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.46.tgz#c88a6fedc766589826db0481602a888864ade1ca" - integrity sha512-UtV0xUA/dibCKKP2JMxOpDtXR74zABevuUEH4K0tvduFSIoxRVcYmQsbB51kXsFTX8MmOyWMt8tuZAlmDOqkrQ== + version "1.4.65" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.65.tgz#c0820db06e268e0a2fd4dbce38fb5376d38ca449" + integrity sha512-0/d8Skk8sW3FxXP0Dd6MnBlrwx7Qo9cqQec3BlIAlvKnrmS3pHsIbaroEi+nd0kZkGpQ6apMEre7xndzjlEnLw== emoji-regex@^8.0.0: version "8.0.0" @@ -3588,16 +3638,16 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: once "^1.4.0" engine.io-parser@~5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.2.tgz#69a2ec3ed431da021f0666712d07f106bcffa6ce" - integrity sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g== + version "5.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" + integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== dependencies: - base64-arraybuffer "~1.0.1" + "@socket.io/base64-arraybuffer" "~1.0.2" engine.io@~6.1.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.1.tgz#2e87680feedabe380e506594f5bfd34cde955d87" - integrity sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ== + version "6.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" + integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== dependencies: "@types/cookie" "^0.4.1" "@types/cors" "^2.8.12" @@ -3618,7 +3668,7 @@ enhanced-resolve@^5.8.3: graceful-fs "^4.2.4" tapable "^2.2.0" -enquirer@^2.3.5, enquirer@~2.3.6: +enquirer@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== @@ -3841,15 +3891,15 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" - integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" + integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== eslint@^8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.6.0.tgz#4318c6a31c5584838c1a2e940c478190f58d558e" - integrity sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw== + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d" + integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ== dependencies: "@eslint/eslintrc" "^1.0.5" "@humanwhocodes/config-array" "^0.9.2" @@ -3858,11 +3908,10 @@ eslint@^8.6.0: cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" eslint-scope "^7.1.0" eslint-utils "^3.0.0" - eslint-visitor-keys "^3.1.0" + eslint-visitor-keys "^3.2.0" espree "^9.3.0" esquery "^1.4.0" esutils "^2.0.2" @@ -3871,7 +3920,7 @@ eslint@^8.6.0: functional-red-black-tree "^1.0.1" glob-parent "^6.0.1" globals "^13.6.0" - ignore "^4.0.6" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" @@ -3882,9 +3931,7 @@ eslint@^8.6.0: minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" regexpp "^3.2.0" - semver "^7.2.1" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" @@ -4277,20 +4324,10 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flatted@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flatted@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" - integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== - -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== +flatted@^3.1.0, flatted@^3.2.4: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== follow-redirects@^1.0.0: version "1.14.7" @@ -4302,6 +4339,11 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.3.tgz#be65b0f20762ef27e1e793860bc2dfb716e99e65" + integrity sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg== + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -4320,7 +4362,7 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@10.0.0: +fs-extra@10.0.0, fs-extra@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== @@ -4329,15 +4371,6 @@ fs-extra@10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -4414,7 +4447,7 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -4538,9 +4571,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" - integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== dependencies: type-fest "^0.20.2" @@ -4564,14 +4597,14 @@ globby@^11.0.1, globby@^11.0.4: slash "^3.0.0" globby@^12.0.0, globby@^12.0.2: - version "12.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-12.0.2.tgz#53788b2adf235602ed4cabfea5c70a1139e1ab11" - integrity sha512-lAsmb/5Lww4r7MM9nCCliDZVIKbZTavrsunAsHLr9oHthrZP1qi7/gAnHOsUs9bLvEt2vKVJhHmxuL7QbDuPdQ== + version "12.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22" + integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA== dependencies: array-union "^3.0.1" dir-glob "^3.0.1" fast-glob "^3.2.7" - ignore "^5.1.8" + ignore "^5.1.9" merge2 "^1.4.1" slash "^4.0.0" @@ -4817,11 +4850,11 @@ http-proxy-agent@^4.0.1: debug "4" http-proxy-middleware@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" - integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz#94d7593790aad6b3de48164f13792262f656c332" + integrity sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g== dependencies: - "@types/http-proxy" "^1.17.5" + "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" is-glob "^4.0.1" is-plain-obj "^3.0.0" @@ -4905,7 +4938,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.4, ignore@^5.1.8, ignore@^5.2.0: +ignore@^5.0.4, ignore@^5.1.8, ignore@^5.1.9, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== @@ -4986,11 +5019,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -5119,7 +5147,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0, is-core-module@^2.8.0: +is-core-module@^2.2.0, is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== @@ -5285,7 +5313,7 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-what@^3.12.0: +is-what@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== @@ -5367,9 +5395,9 @@ istanbul-lib-source-maps@^4.0.1: source-map "^0.6.1" istanbul-reports@^3.0.5: - version "3.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" - integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -5402,10 +5430,10 @@ jasmine-core@~4.0.0: resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.0.0.tgz#8299ed38a100c47a1d154af63449a40967a7be5c" integrity sha512-tq24OCqHElgU9KDpb/8O21r1IfotgjIzalfW9eCmRR40LZpvwXT68iariIyayMwi0m98RDt16aljdbwK0sBMmQ== -jest-worker@^27.4.1: - version "27.4.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" - integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw== +jest-worker@^27.4.5: + version "27.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.0.tgz#99ee77e4d06168107c27328bd7f54e74c3a48d59" + integrity sha512-8OEHiPNOPTfaWnJ2SUHM8fmgeGq37uuGsQBvGKQJl1f+6WIy6g7G3fE2ruI5294bUKUI9FaCWt5hDvO8HSwsSg== dependencies: "@types/node" "*" merge-stream "^2.0.0" @@ -5500,13 +5528,6 @@ jsonc-parser@3.0.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -5534,9 +5555,9 @@ karma-chrome-launcher@~3.1.0: which "^1.2.1" karma-coverage@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.1.0.tgz#843564578d9e1fb889ec141a582c019bb6db14db" - integrity sha512-uIejpnArNFQIovB6EPsKO/T4XofELdJWXcA2ADXztFlKhHbr0Ws6ba7wKTMVWsIhEs4iJxdhQkCQrkkhFJSZCw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.1.1.tgz#7434f8736841e08de3e6c302632e8d239634f388" + integrity sha512-oxeOSBVK/jdZsiX03LhHQkO4eISSQb5GbHi6Nsw3Mw7G4u6yUgacBAftnO7q+emPBLMsrNbz1pGIrj+Jb3z17A== dependencies: istanbul-lib-coverage "^3.2.0" istanbul-lib-instrument "^4.0.3" @@ -5565,9 +5586,9 @@ karma-source-map-support@1.4.0: source-map-support "^0.5.5" karma@~6.3.10: - version "6.3.11" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.11.tgz#2c2fb09f1a9f52e1a0739adeedace2a68d4c0d34" - integrity sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ== + version "6.3.15" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.15.tgz#6c3beedb2440b05589a502462140afed724481e7" + integrity sha512-4O5X6zVFdmwo/fgjRN84fPG3IvaiOxOjIeZBwBrQYz4nIyGqlF8Wm7C1Hr7idQ9NHgnvJM+LSjZwS1C+qALMGw== dependencies: body-parser "^1.19.0" braces "^3.0.2" @@ -5581,9 +5602,10 @@ karma@~6.3.10: http-proxy "^1.18.1" isbinaryfile "^4.0.8" lodash "^4.17.21" - log4js "^6.3.0" + log4js "^6.4.1" mime "^2.5.2" minimatch "^3.0.4" + mkdirp "^0.5.5" qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" @@ -5608,9 +5630,9 @@ keyv@^3.0.0: json-buffer "3.0.0" keyv@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.5.tgz#bb12b467aba372fab2a44d4420c00d3c4ebd484c" - integrity sha512-531pkGLqV3BMg0eDqqJFI0R1mkK1Nm5xIP2mM6keP5P8WfFtCkg2IOwplTUmlGoTgIg9yQYZ/kdihhz89XH3vA== + version "4.1.1" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.1.1.tgz#02c538bfdbd2a9308cc932d4096f05ae42bfa06a" + integrity sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ== dependencies: json-buffer "3.0.1" @@ -5744,16 +5766,16 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" - integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== +log4js@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.1.tgz#9d3a8bf2c31c1e213fe3fc398a6053f7a2bc53e8" + integrity sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg== dependencies: - date-format "^3.0.0" - debug "^4.1.1" - flatted "^2.0.1" - rfdc "^1.1.4" - streamroller "^2.2.4" + date-format "^4.0.3" + debug "^4.3.3" + flatted "^3.2.4" + rfdc "^1.3.0" + streamroller "^3.0.2" logalot@^2.1.0: version "2.1.0" @@ -5884,7 +5906,7 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -memfs@^3.2.2: +memfs@^3.2.2, memfs@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== @@ -5940,7 +5962,7 @@ mime-db@1.51.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.28.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== @@ -5989,13 +6011,20 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimatch@^3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== + dependencies: + brace-expansion "^1.1.7" + minimist@1.2.5, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -6113,10 +6142,10 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nanoid@^3.1.30: - version "3.1.32" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.32.tgz#8f96069e6239cc0a9ae8c0d3b41a3b4933a88c0a" - integrity sha512-F8mf7R3iT9bvThBoW4tGXhXFHCctyCiUUPrWF8WaTqa3h96d9QybkSeba43XVOOE3oiLfkVDe4bT8MeGmkrTxw== +nanoid@^3.1.30, nanoid@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== napi-build-utils@^1.0.1: version "1.0.2" @@ -6137,10 +6166,10 @@ needle@^2.5.2: iconv-lite "^0.4.4" sax "^1.2.4" -negotiator@0.6.2, negotiator@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3, negotiator@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.6.2: version "2.6.2" @@ -6358,11 +6387,6 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -6375,12 +6399,12 @@ nx@13.1.3: dependencies: "@nrwl/cli" "*" -nx@13.4.5: - version "13.4.5" - resolved "https://registry.yarnpkg.com/nx/-/nx-13.4.5.tgz#f68857ea33dae302c0d1171f0909155ab0be2bd7" - integrity sha512-efUyCh6jgBWh8SIXoxa33M+pwLQyEbsjb0g6qoNORAibmzHlf0aI79t3pn7Ru2O33D+GTU3qQ/DJVxbE9M/2zg== +nx@13.7.3: + version "13.7.3" + resolved "https://registry.yarnpkg.com/nx/-/nx-13.7.3.tgz#8dc2af983e519b75121649dd43217b84c293f55d" + integrity sha512-LTj2V0+f1FIHIvPCGMDw3FilWBgNujGcjxJ85A1Pdkoy1Ovr4Onhv1BNfDpjzy9UB0zNgkTfMQzSiEzK6+p2fA== dependencies: - "@nrwl/cli" "13.4.5" + "@nrwl/cli" "13.7.3" object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" @@ -6763,10 +6787,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -peek-readable@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.2.tgz#a5cb847e347d3eccdc37642c82d2b4155c1ab8af" - integrity sha512-9fMaz6zoxw9ypO1KZy5RDJgSupEtu0Q+g/OqqsVHX3rKGR8qehRLYzsFARZ4bVvdvfknKiXvuDbkMnO1g6cRpQ== +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== pend@~1.2.0: version "1.2.0" @@ -6847,138 +6871,104 @@ portfinder@^1.0.28: debug "^3.1.1" mkdirp "^0.5.5" -postcss-attribute-case-insensitive@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" - integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^6.0.2" - -postcss-color-functional-notation@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" - integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-color-gray@^5.0.0: +postcss-attribute-case-insensitive@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" - integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.0.tgz#39cbf6babf3ded1e4abf37d09d6eda21c644105c" + integrity sha512-b4g9eagFGq9T5SWX4+USfVyjIb3liPnjhHHRMP7FMB2kFVpYyfEscV0wP3eaXhKlcHKUut8lt5BGoeylWA/dBQ== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.5" - postcss-values-parser "^2.0.0" + postcss-selector-parser "^6.0.2" -postcss-color-hex-alpha@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" - integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== +postcss-color-functional-notation@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz#f59ccaeb4ee78f1b32987d43df146109cc743073" + integrity sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ== dependencies: - postcss "^7.0.14" - postcss-values-parser "^2.0.1" + postcss-value-parser "^4.2.0" -postcss-color-mod-function@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" - integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== +postcss-color-hex-alpha@^8.0.2: + version "8.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz#61a0fd151d28b128aa6a8a21a2dad24eebb34d52" + integrity sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-color-rebeccapurple@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" - integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== +postcss-color-rebeccapurple@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.0.2.tgz#5d397039424a58a9ca628762eb0b88a61a66e079" + integrity sha512-SFc3MaocHaQ6k3oZaFwH8io6MdypkUtEy/eXzXEB1vEQlO3S3oDc/FSZA8AsS04Z25RirQhlDlHLh3dn7XewWw== dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-custom-media@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" - integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== - dependencies: - postcss "^7.0.14" +postcss-custom-media@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" + integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== -postcss-custom-properties@^8.0.11: - version "8.0.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" - integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== +postcss-custom-properties@^12.1.2: + version "12.1.4" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz#e3d8a8000f28094453b836dff5132385f2862285" + integrity sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw== dependencies: - postcss "^7.0.17" - postcss-values-parser "^2.0.1" + postcss-value-parser "^4.2.0" -postcss-custom-selectors@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" - integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== +postcss-custom-selectors@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.0.tgz#022839e41fbf71c47ae6e316cb0e6213012df5ef" + integrity sha512-/1iyBhz/W8jUepjGyu7V1OPcGbc636snN1yXEQCinb6Bwt7KxsiU7/bLQlp8GwAXzCh7cobBU5odNn/2zQWR8Q== dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" + postcss-selector-parser "^6.0.4" -postcss-dir-pseudo-class@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" - integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== +postcss-dir-pseudo-class@^6.0.3: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz#9afe49ea631f0cb36fa0076e7c2feb4e7e3f049c" + integrity sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw== dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" + postcss-selector-parser "^6.0.9" -postcss-double-position-gradients@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" - integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== +postcss-double-position-gradients@^3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.5.tgz#f6b755e9850bb9816dfbf8fa346d9ce2e8a03848" + integrity sha512-XiZzvdxLOWZwtt/1GgHJYGoD9scog/DD/yI5dcvPrXNdNDEv7T53/6tL7ikl+EM3jcerII5/XIQzd1UHOdTi2w== dependencies: - postcss "^7.0.5" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-env-function@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" - integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== +postcss-env-function@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.5.tgz#b9614d50abd91e4c88a114644a9766880dabe393" + integrity sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA== dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-focus-visible@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" - integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== +postcss-focus-visible@^6.0.3: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== dependencies: - postcss "^7.0.2" + postcss-selector-parser "^6.0.9" -postcss-focus-within@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" - integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== +postcss-focus-within@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== dependencies: - postcss "^7.0.2" + postcss-selector-parser "^6.0.9" -postcss-font-variant@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" - integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== - dependencies: - postcss "^7.0.2" +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== -postcss-gap-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" - integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== - dependencies: - postcss "^7.0.2" +postcss-gap-properties@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz#6401bb2f67d9cf255d677042928a70a915e6ba60" + integrity sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ== -postcss-image-set-function@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" - integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== +postcss-image-set-function@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz#bcff2794efae778c09441498f40e0c77374870a9" + integrity sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A== dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" postcss-import@14.0.2: version "14.0.2" @@ -6989,21 +6979,17 @@ postcss-import@14.0.2: read-cache "^1.0.0" resolve "^1.1.7" -postcss-initial@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" - integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== - dependencies: - postcss "^7.0.2" +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-lab-function@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" - integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== +postcss-lab-function@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.0.4.tgz#504747ab2754e046fb01e72779bbb434a05357df" + integrity sha512-TAEW8X/ahMYV33mvLFQARtBPAy1VVJsiR9VVx3Pcbu+zlqQj0EIyJ/Ie1/EwxwIt530CWtEDzzTXBDzfdb+qIQ== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" postcss-loader@6.2.1: version "6.2.1" @@ -7014,19 +7000,15 @@ postcss-loader@6.2.1: klona "^2.0.5" semver "^7.3.5" -postcss-logical@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" - integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== - dependencies: - postcss "^7.0.2" +postcss-logical@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== -postcss-media-minmax@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" - integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== - dependencies: - postcss "^7.0.2" +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== postcss-modules-extract-imports@^3.0.0: version "3.0.0" @@ -7056,140 +7038,101 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" - integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== +postcss-nesting@^10.1.2: + version "10.1.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.2.tgz#2e5f811b3d75602ea18a95dd445bde5297145141" + integrity sha512-dJGmgmsvpzKoVMtDMQQG/T6FSqs6kDtUDirIfl4KnjMCiY9/ETX8jdKyCd20swSRAbUYkaBKV20pxkzxoOXLqQ== dependencies: - postcss "^7.0.2" + postcss-selector-parser "^6.0.8" -postcss-overflow-shorthand@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" - integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== - dependencies: - postcss "^7.0.2" +postcss-overflow-shorthand@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz#ebcfc0483a15bbf1b27fdd9b3c10125372f4cbc2" + integrity sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg== -postcss-page-break@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" - integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== - dependencies: - postcss "^7.0.2" +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== -postcss-place@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" - integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-preset-env@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" - integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== - dependencies: - autoprefixer "^9.6.1" - browserslist "^4.6.4" - caniuse-lite "^1.0.30000981" - css-blank-pseudo "^0.1.4" - css-has-pseudo "^0.10.0" - css-prefers-color-scheme "^3.1.1" - cssdb "^4.4.0" - postcss "^7.0.17" - postcss-attribute-case-insensitive "^4.0.1" - postcss-color-functional-notation "^2.0.1" - postcss-color-gray "^5.0.0" - postcss-color-hex-alpha "^5.0.3" - postcss-color-mod-function "^3.0.3" - postcss-color-rebeccapurple "^4.0.1" - postcss-custom-media "^7.0.8" - postcss-custom-properties "^8.0.11" - postcss-custom-selectors "^5.1.2" - postcss-dir-pseudo-class "^5.0.0" - postcss-double-position-gradients "^1.0.0" - postcss-env-function "^2.0.2" - postcss-focus-visible "^4.0.0" - postcss-focus-within "^3.0.0" - postcss-font-variant "^4.0.0" - postcss-gap-properties "^2.0.0" - postcss-image-set-function "^3.0.1" - postcss-initial "^3.0.0" - postcss-lab-function "^2.0.1" - postcss-logical "^3.0.0" - postcss-media-minmax "^4.0.0" - postcss-nesting "^7.0.0" - postcss-overflow-shorthand "^2.0.0" - postcss-page-break "^2.0.0" - postcss-place "^4.0.1" - postcss-pseudo-class-any-link "^6.0.0" - postcss-replace-overflow-wrap "^3.0.0" - postcss-selector-matches "^4.0.0" - postcss-selector-not "^4.0.0" - -postcss-pseudo-class-any-link@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" - integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== +postcss-place@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.4.tgz#eb026650b7f769ae57ca4f938c1addd6be2f62c9" + integrity sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg== dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" + postcss-value-parser "^4.2.0" -postcss-replace-overflow-wrap@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" - integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== +postcss-preset-env@7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.2.3.tgz#01b9b6eea0ff16c27a3d514f10105d56363428a6" + integrity sha512-Ok0DhLfwrcNGrBn8sNdy1uZqWRk/9FId0GiQ39W4ILop5GHtjJs8bu1MY9isPwHInpVEPWjb4CEcEaSbBLpfwA== dependencies: - postcss "^7.0.2" - -postcss-selector-matches@^4.0.0: + autoprefixer "^10.4.2" + browserslist "^4.19.1" + caniuse-lite "^1.0.30001299" + css-blank-pseudo "^3.0.2" + css-has-pseudo "^3.0.3" + css-prefers-color-scheme "^6.0.2" + cssdb "^5.0.0" + postcss-attribute-case-insensitive "^5.0.0" + postcss-color-functional-notation "^4.2.1" + postcss-color-hex-alpha "^8.0.2" + postcss-color-rebeccapurple "^7.0.2" + postcss-custom-media "^8.0.0" + postcss-custom-properties "^12.1.2" + postcss-custom-selectors "^6.0.0" + postcss-dir-pseudo-class "^6.0.3" + postcss-double-position-gradients "^3.0.4" + postcss-env-function "^4.0.4" + postcss-focus-visible "^6.0.3" + postcss-focus-within "^5.0.3" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.2" + postcss-image-set-function "^4.0.4" + postcss-initial "^4.0.1" + postcss-lab-function "^4.0.3" + postcss-logical "^5.0.3" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.1.2" + postcss-overflow-shorthand "^3.0.2" + postcss-page-break "^3.0.4" + postcss-place "^7.0.3" + postcss-pseudo-class-any-link "^7.0.2" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^5.0.0" + +postcss-pseudo-class-any-link@^7.0.2: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz#534eb1dadd9945eb07830dbcc06fb4d5d865b8e0" + integrity sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-replace-overflow-wrap@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" - integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== -postcss-selector-not@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" - integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: +postcss-selector-not@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-5.0.0.tgz#ac5fc506f7565dd872f82f5314c0f81a05630dc7" + integrity sha512-/2K3A4TCP9orP4TNS7u3tGdRFVKqz/E6pX3aGnriPG0jU78of8wsUcqE4QAhWEU0d+WnMSF93Ah3F//vUtK+iQ== dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + balanced-match "^1.0.0" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.8" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914" - integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ== +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.8, postcss-selector-parser@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" - integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - postcss@8.4.4: version "8.4.4" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.4.tgz#d53d4ec6a75fd62557a66bb41978bf47ff0c2869" @@ -7199,7 +7142,7 @@ postcss@8.4.4: picocolors "^1.0.0" source-map-js "^1.0.1" -postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.35: version "7.0.39" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== @@ -7208,13 +7151,13 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0. source-map "^0.6.1" postcss@^8.2.15, postcss@^8.3.7: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + version "8.4.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" + integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== dependencies: - nanoid "^3.1.30" + nanoid "^3.2.0" picocolors "^1.0.0" - source-map-js "^1.0.1" + source-map-js "^1.0.2" prebuild-install@^6.1.2: version "6.1.4" @@ -7261,9 +7204,9 @@ primeicons@^5.0.0: integrity sha512-heygWF0X5HFI1otlZE62pp6ye7sZ8om78J9au2BRkg8O7Y8AHTZ9qKMRzchZUHLe8zUAvdi6hZzzm9XxgwIExw== primeng@^13.0.4: - version "13.0.4" - resolved "https://registry.yarnpkg.com/primeng/-/primeng-13.0.4.tgz#8ffb5195406c0359d62594c6aaad620f1b7011a2" - integrity sha512-hX6TcZ5UwCzA3cfl9csk/N9l0R9mek/QR/BWDQI2zH9Jtc5W1x9FUXnZPj4pUlCDvYL5NW21Yu7d9fDhIe20qQ== + version "13.1.0" + resolved "https://registry.yarnpkg.com/primeng/-/primeng-13.1.0.tgz#d520cc8ea618c558ba096773bd9cd63ad1407a34" + integrity sha512-Pw4vDFTiE9DIzPVnm/b9o4aadsuMXOtADfhQtJaMpC4WUP+PggmxnooUkbhNneXtELLRN95eJ1znK4tA433dYA== dependencies: tslib "^2.3.0" @@ -7272,11 +7215,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -7493,10 +7431,10 @@ reflect-metadata@^0.1.2: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== -regenerate-unicode-properties@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" - integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== dependencies: regenerate "^1.4.2" @@ -7535,15 +7473,15 @@ regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^4.7.1: - version "4.8.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" - integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== dependencies: regenerate "^1.4.2" - regenerate-unicode-properties "^9.0.0" - regjsgen "^0.5.2" - regjsparser "^0.7.0" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" @@ -7561,15 +7499,15 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -regjsgen@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== -regjsparser@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" - integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== dependencies: jsesc "~0.5.0" @@ -7595,11 +7533,6 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -7640,11 +7573,11 @@ resolve@1.20.0: path-parse "^1.0.6" resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2: - version "1.21.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" - integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.8.0" + is-core-module "^2.8.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -7685,7 +7618,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.1.4: +rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== @@ -7871,7 +7804,7 @@ semver@7.3.4: dependencies: lru-cache "^6.0.0" -semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -8000,9 +7933,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-concat@^1.0.0: version "1.0.1" @@ -8010,9 +7943,9 @@ simple-concat@^1.0.0: integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^3.0.3, simple-get@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== dependencies: decompress-response "^4.2.0" once "^1.3.1" @@ -8035,7 +7968,7 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -smart-buffer@^4.1.0: +smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -8085,12 +8018,12 @@ socks-proxy-agent@^6.0.0: socks "^2.6.1" socks@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" - integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + version "2.6.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" + integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== dependencies: ip "^1.1.5" - smart-buffer "^4.1.0" + smart-buffer "^4.2.0" sort-keys-length@^1.0.0: version "1.0.1" @@ -8118,10 +8051,10 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== +source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== source-map-loader@3.0.0: version "3.0.0" @@ -8248,14 +8181,14 @@ ssri@^8.0.0, ssri@^8.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -streamroller@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" - integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== +streamroller@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7" + integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA== dependencies: - date-format "^2.1.0" + date-format "^4.0.3" debug "^4.1.1" - fs-extra "^8.1.0" + fs-extra "^10.0.0" strict-uri-encode@^1.0.0: version "1.1.0" @@ -8364,12 +8297,12 @@ strip-outer@^1.0.0: escape-string-regexp "^1.0.2" strtok3@^6.2.4: - version "6.2.4" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.4.tgz#302aea64c0fa25d12a0385069ba66253fdc38a81" - integrity sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw== + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== dependencies: "@tokenizer/token" "^0.3.0" - peek-readable "^4.0.1" + peek-readable "^4.1.0" stylus-loader@6.2.0: version "6.2.0" @@ -8495,11 +8428,11 @@ tempfile@^2.0.0: uuid "^3.0.1" terser-webpack-plugin@^5.1.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" - integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" + integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== dependencies: - jest-worker "^27.4.1" + jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.0" source-map "^0.6.1" @@ -8676,9 +8609,9 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@~4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" - integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== ua-parser-js@^0.7.30: version "0.7.31" @@ -8716,11 +8649,6 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -8742,11 +8670,6 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -8900,12 +8823,12 @@ webpack-dev-middleware@5.2.2: schema-utils "^4.0.0" webpack-dev-middleware@^5.2.1: - version "5.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" - integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== dependencies: colorette "^2.0.10" - memfs "^3.2.2" + memfs "^3.4.1" mime-types "^2.1.31" range-parser "^1.2.1" schema-utils "^4.0.0" @@ -9005,11 +8928,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - which@^1.2.1, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -9057,15 +8975,6 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -9110,11 +9019,6 @@ xtend@^4.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -9140,14 +9044,6 @@ yargs-parser@20.0.0: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.0.0.tgz#c65a1daaa977ad63cebdd52159147b789a4e19a9" integrity sha512-8eblPHTL7ZWRkyjIZJjnGf+TijiKJSwA24svzLRVvtgoi/RZiKa9fFQTrlx0OKLnyHSdt/enrdadji6WFfESVA== -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" @@ -9158,23 +9054,6 @@ yargs-parser@^21.0.0: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== -yargs@15.4.1: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - yargs@^16.1.1: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"