diff --git a/.cargo/config.toml b/.cargo/config.toml index 6330d419..1ecf5a7b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ # Needed for WASM unstable features [build] -rustflags = [ "--cfg=web_sys_unstable_apis" ] -rustdocflags = [ "--cfg=web_sys_unstable_apis" ] -#target = "wasm32-unknown-unknown" +rustflags = ["--cfg=web_sys_unstable_apis"] +rustdocflags = ["--cfg=web_sys_unstable_apis"] +target = "wasm32-unknown-unknown" diff --git a/.gitignore b/.gitignore index 3ffe4ce7..ed4b9df2 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,9 @@ venv/ # proptest regression tests proptest-regressions/ + +# samply profile +profile.json + +# webdriver configs +webdriver.json diff --git a/Cargo.toml b/Cargo.toml index eae21a07..d69df143 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,11 @@ members = [ "crates/ratchet-hub", "crates/ratchet-core", - "crates/ratchet-web", + "crates/ratchet-web-train", "crates/ratchet-loader", "crates/ratchet-models", "crates/ratchet-nn", "crates/ratchet-hub", - "crates/ratchet-cli", "crates/ratchet-macros", "crates/ratchet-datasets", ] @@ -28,7 +27,7 @@ inherits = "release" debug = 2 [workspace.dependencies] -wgpu = { git = "https://github.com/vinhowe/wgpu", branch = "feature/multi-dim-compute-subgroups", features = [ +wgpu = { git = "https://github.com/vinhowe/wgpu", branch = "feature/extract-webgpu-gpubuffer", features = [ "fragile-send-sync-non-atomic-wasm", ] } bytemuck = { version = "1.14.0", features = [ @@ -49,7 +48,7 @@ anyhow = "1.0.79" tokenizers = "0.19.1" js-sys = "0.3.64" -wasm-bindgen = "0.2.91" +wasm-bindgen = "0.2.100" wasm-bindgen-test = "0.3.34" cfg-if = "1.0.0" chrono = "0.4.35" diff --git a/README.md b/README.md index 11980782..5c94cccf 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,8 @@ -

- For the time being, I don't have instructions on how to run this. You're on your own for a tiny bit :) -

+# toy transformer -
- -

-(backward) -

-
-
+Watch a toy model train, in your browser, with WebGPU. + +## Attribution This is a fork of [Ratchet](https://github.com/huggingface/ratchet), hacked and butchered to add backpropogation, to show that it is technically possible to train language models in a (WebGPU-enabled) browser. diff --git a/crates/ratchet-cli/Cargo.toml b/crates/ratchet-cli/Cargo.toml deleted file mode 100644 index 014bf678..00000000 --- a/crates/ratchet-cli/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "ratchet-cli" -version = "0.1.0" -edition = "2021" - -[[bin]] -name = "ratchet" -path = "src/bin/cli.rs" - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -ratchet = { path = "../ratchet-core" } -ratchet-loader = { path = "../ratchet-loader" } -ratchet-models = { path = "../ratchet-models" } -ratchet-hub = { path = "../ratchet-hub" } -ratchet-nn = { path = "../ratchet-nn" } -log.workspace = true -clap = { workspace = true, features = ["derive"] } -hf-hub = { workspace = true } -serde_json = { workspace = true } -env_logger = { workspace = true } -fern = { workspace = true } -chrono = { workspace = true } -tokenizers = { workspace = true } -ndarray = { workspace = true } -ndarray-stats = { workspace = true } -anyhow.workspace = true diff --git a/crates/ratchet-cli/src/bin/cli.rs b/crates/ratchet-cli/src/bin/cli.rs deleted file mode 100644 index 08eb3e3b..00000000 --- a/crates/ratchet-cli/src/bin/cli.rs +++ /dev/null @@ -1,253 +0,0 @@ -#[cfg(not(target_arch = "wasm32"))] -mod cli { - use clap::{value_parser, Arg, ArgMatches, Command}; - use hf_hub::api::sync::Api; - use ndarray::Axis; - use ndarray_stats::QuantileExt; - use ratchet::{shape, Device, DeviceRequest, Tensor}; - use ratchet_loader::gguf::gguf::{self, Header}; - use ratchet_models::registry::{ - AvailableModels, Quantization, WhisperVariants as RegistryWhisper, - }; - use ratchet_models::whisper::options::DecodingOptionsBuilder; - use ratchet_models::whisper::transcribe::transcribe; - use ratchet_models::{phi2::Phi2, whisper::Whisper}; - use ratchet_nn::Module; - use std::io::Write; - use std::path::Path; - use std::process::Command as TermCommand; - use tokenizers::Tokenizer; - - fn ffmpeg_preproc>(path: P) -> Vec { - let path = path.as_ref(); - let output = TermCommand::new("ffmpeg") - .args([ - "-nostdin", - "-threads", - "0", - "-i", - path.to_str().unwrap(), - "-f", - "s16le", - "-ac", - "1", - "-acodec", - "pcm_s16le", - "-loglevel", - "error", - "-ar", - "16000", - "-", - ]) - .output() - .expect("Failed to execute ffmpeg command"); - - if !output.status.success() { - panic!( - "ffmpeg command failed: {}", - String::from_utf8_lossy(&output.stderr) - ); - } - - let audio_data = output.stdout; - let mut samples = Vec::new(); - - for chunk in audio_data.chunks(2) { - let sample = i16::from_le_bytes([chunk[0], chunk[1]]) as f32 / 32768.0; - samples.push(sample); - } - - samples - } - - pub fn start_logger() { - let logger = fern::Dispatch::new() - .format(|out, message, record| { - out.finish(format_args!( - "{}[{}][{}] {}", - chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), - record.target(), - record.level(), - message - )) - }) - .level_for("tokenizers", log::LevelFilter::Off) - .level(log::LevelFilter::Warn) - .apply(); - match logger { - Ok(_) => log::info!("Logging initialized."), - Err(error) => eprintln!("Error initializing logging: {:?}", error), - } - } - - fn handle_whisper(matches: &ArgMatches, api: Api) { - let quantization = matches - .get_one::("quantization") - .unwrap_or(&Quantization::Q8_0); - - let mut whisper = if let Some(variant) = matches.get_one::("variant") { - let model = AvailableModels::Whisper(variant.clone()); - let repo = api.model(model.repo_id()); - let model_path = repo.get(&model.model_id(quantization.clone())).unwrap(); - println!("MODEL PATH: {}", model_path.display()); - - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path).unwrap()); - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - let header = gguf::Header::read(&mut reader).unwrap(); - Whisper::load(header, variant.clone(), &mut reader, device).unwrap() - } else { - panic!("Model not found"); - }; - - if let Some(input) = matches.get_one::("input") { - let options = DecodingOptionsBuilder::new().build(); - let samples = ffmpeg_preproc(input); - let transcript = - transcribe(&mut whisper, samples, options, Some(|s| println!("{}", s))).unwrap(); - log::info!("Processing time: {:?}", transcript.processing_time); - } else { - panic!("Input file not found"); - }; - } - - fn handle_phi2(matches: &ArgMatches, api: Api) -> anyhow::Result<()> { - let _ = env_logger::builder().is_test(true).try_init(); - let model_repo = api.model("FL33TW00D-HF/phi2".to_string()); - let model_path = model_repo.get("phi2-q8_0.gguf").unwrap(); - println!("MODEL PATH: {}", model_path.display()); - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path)?); - let device = Device::request_device(DeviceRequest::GPU)?; - let content = Header::read(&mut reader)?; - let mut model = Phi2::load(content, &mut reader, &device)?; - - let tokenizer = - Tokenizer::from_file(concat!("../../", "/models/microsoft/phi-2/tokenizer.json")) - .unwrap(); - - let prompt = if let Some(prompt) = matches.get_one::("prompt") { - prompt - } else { - "def print_prime(n):" - }; - - let max_tokens = matches.get_one::("max-tokens").unwrap(); - - let encoding = tokenizer.encode(prompt, true).unwrap(); - let mut tokens = encoding - .get_ids() - .iter() - .map(|&x| x as i32) - .collect::>(); - - print!("{}", prompt); - std::io::stdout().flush().unwrap(); - let mut all_tokens = tokens.clone(); - let mut loop_cnt = 0; - let start_time = std::time::Instant::now(); - while tokens[tokens.len() - 1] != 50256 && loop_cnt < *max_tokens { - let input = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let result = model.schedule(input)?.full()?.resolve()?; - let logits = result.to(&Device::CPU)?; - model.cache_mut().update(tokens.len()); - - tokens = logits - .to_ndarray_view::() - .map_axis(Axis(2), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - let u32_toks = tokens.iter().map(|&x| x as u32).collect::>(); - print!("{}", tokenizer.decode(&u32_toks, true).unwrap()); - std::io::stdout().flush().unwrap(); - all_tokens.extend(tokens.clone()); - loop_cnt += 1; - } - let elapsed = start_time.elapsed(); - println!("\nElapsed time: {:?}", elapsed); - println!( - "tok/sec: {}", - all_tokens.len() as f64 / elapsed.as_secs_f64() - ); - Ok(()) - } - - #[cfg(not(target_arch = "wasm32"))] - fn main() -> Result<(), Box> { - env_logger::init(); - let matches = Command::new("ratchet") - .about("LLM & VLM CLI") - .version("0.1.0") - .subcommand_required(true) - .arg_required_else_help(true) - .subcommand( - Command::new("whisper") - .long_about( - "Cross-platform, GPU accelerated implementation of OpenAI's Whisper Model.", - ) - .arg( - Arg::new("variant") - .short('v') - .long("variant") - .default_value("small") - .help("Whisper model variant to use.") - .value_parser(value_parser!(RegistryWhisper)), - ) - .arg( - Arg::new("quantization") - .short('q') - .long("quantization") - .default_value("f32") - .help("Model quantization to use.") - .value_parser(value_parser!(Quantization)), - ) - .arg( - Arg::new("input") - .short('i') - .long("input") - .required(true) - .help("Path to the input file"), - ), - ) - .subcommand( - Command::new("phi2") - .long_about( - "Cross-platform, GPU accelerated implementation of Microsoft's Phi2 model.", - ) - .arg( - Arg::new("prompt") - .short('p') - .long("prompt") - .required(true) - .help("Input prompt."), - ) - .arg( - Arg::new("max-tokens") - .short('m') - .long("max-tokens") - .default_value("256") - .value_parser(value_parser!(usize)) - .help("Maximum number of tokens to generate."), - ), - ) - .get_matches(); - - let api = Api::new().unwrap(); - if let Some(matches) = matches.subcommand_matches("phi2") { - let _ = handle_phi2(matches, api); - } else if let Some(matches) = matches.subcommand_matches("whisper") { - handle_whisper(matches, api); - } - - Ok(()) - } -} - -#[cfg(not(target_arch = "wasm32"))] -fn main() { - cli::main(); -} - -#[cfg(target_arch = "wasm32")] -fn main() { - // Empty function to get the CLI to compile anyway -} diff --git a/crates/ratchet-cli/src/lib.rs b/crates/ratchet-cli/src/lib.rs deleted file mode 100644 index 8b137891..00000000 --- a/crates/ratchet-cli/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/ratchet-core/Cargo.toml b/crates/ratchet-core/Cargo.toml index ef2e9f68..7433c476 100644 --- a/crates/ratchet-core/Cargo.toml +++ b/crates/ratchet-core/Cargo.toml @@ -71,6 +71,10 @@ maybe-async = { workspace = true } async-trait = "0.1.77" smallvec = { workspace = true, features = ["serde"] } +[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] +features = ["GpuBuffer", "GpuDevice"] +workspace = true + [dev-dependencies] env_logger = { workspace = true } rand = { workspace = true } diff --git a/crates/ratchet-core/src/backprop.rs b/crates/ratchet-core/src/backprop.rs index 875977e7..afc8f425 100644 --- a/crates/ratchet-core/src/backprop.rs +++ b/crates/ratchet-core/src/backprop.rs @@ -3,9 +3,9 @@ /// Methods for backpropagation of gradients. use crate::ops::{BinaryOp, UnaryOp}; use crate::{ - rvec, Affine, Alibi, Binary, Broadcast, Cmp, Concat, Conv, DType, Gather, GroupNorm, IndexAdd, - IndexSelect, LazyOp, Matmul, Norm, NormOp, Permute, Powf, Reduce, ReduceOp, Reindex, RoPE, - ScatterAdd, Shape, Slice, Softmax, Tensor, TensorId, Unary, View, WhereCond, + rvec, Affine, Alibi, Binary, Broadcast, Cast, Cmp, Concat, Conv, DType, Gather, GroupNorm, + IndexAdd, IndexSelect, LazyOp, Matmul, Norm, NormOp, Permute, Powf, Reduce, ReduceOp, Reindex, + RoPE, ScatterAdd, ScopePusher, Shape, Slice, Softmax, Tensor, TensorId, Unary, View, WhereCond, }; use crate::{HashMap, Trilu}; use anyhow::Result; @@ -174,8 +174,16 @@ impl Tensor { track_grad |= tg; nodes } + LazyOp::Cast(Cast { input, .. }) => { + if input.dt().is_float() { + let (tg, nodes) = walk(input, nodes, already_seen); + track_grad |= tg; + nodes + } else { + nodes + } + } LazyOp::IndexWrite(_) => todo!(), - LazyOp::Cast(_) => todo!(), LazyOp::Copy(_) => todo!(), LazyOp::Detach(_) | LazyOp::Const @@ -186,6 +194,7 @@ impl Tensor { }) | LazyOp::FillConstant(_) | LazyOp::FillRandn(_) + | LazyOp::Bernoulli(_) | LazyOp::Arange(_) | LazyOp::Cache(_) | LazyOp::Trilu(_) => nodes, @@ -203,10 +212,12 @@ impl Tensor { } pub fn backward(&self) -> Result { + let _scope_guard = ScopePusher::new("backward"); let sorted_nodes = self.sorted_nodes(); let mut grads = GradStore::new(); grads.insert(self, self.ones_like::().contiguous()); for node in sorted_nodes.iter() { + let _op_scope_guard = ScopePusher::new(&format!("for:{}", node.op().name())); if node.is_variable() { continue; } @@ -574,6 +585,7 @@ impl Tensor { }) | LazyOp::FillConstant(_) | LazyOp::FillRandn(_) + | LazyOp::Bernoulli(_) | LazyOp::Arange(_) => {} LazyOp::View(View { src: arg, .. }) => { let arg_grad = grad.clone().view(arg.shape().clone())?; @@ -687,12 +699,14 @@ impl Tensor { LazyOp::Alibi(Alibi { input, .. }) => { grads.accumulate_add(input, grad)?; } + LazyOp::Cast(Cast { input, dst_dt }) => { + grads.accumulate_add(input, grad.cast(input.dt())?)?; + } LazyOp::Norm(_) => todo!(), LazyOp::Const => panic!("ratchet internal error - const node in backprop"), LazyOp::Concat(_) => todo!(), LazyOp::Cmp(_) => todo!(), LazyOp::Powf(_) => todo!(), - LazyOp::Cast(_) => todo!(), LazyOp::RoPE(RoPE { input: arg, dim, diff --git a/crates/ratchet-core/src/compiled_op.rs b/crates/ratchet-core/src/compiled_op.rs index 09876e93..46f7b7c6 100644 --- a/crates/ratchet-core/src/compiled_op.rs +++ b/crates/ratchet-core/src/compiled_op.rs @@ -1,12 +1,15 @@ #[cfg(feature = "debug")] use crate::gpu::BindGroupLayoutEntryDescriptor; -use crate::gpu::{ - BindGroupDescriptor, BindGroupLayoutHandle, ComputePipelineHandle, GpuBindGroup, WgpuDevice, - WorkgroupCount, -}; #[cfg(feature = "debug")] use crate::TensorId; use crate::{drvec, rvec, KernelKey, OperationError, PooledGPUBuffer, RVec, Tensor}; +use crate::{ + gpu::{ + BindGroupDescriptor, BindGroupLayoutHandle, ComputePipelineHandle, GpuBindGroup, + WgpuDevice, WorkgroupCount, + }, + TensorId, +}; use derive_new::new; use std::sync::Arc; use wgpu::DynamicOffset; @@ -40,6 +43,11 @@ pub struct CompiledOp { pub(crate) storage_groups: RVec, pub(crate) offset: DynamicOffset, //offset into the metadata uniform buffer pub kernel_key: KernelKey, + // Mapping between tensor and compiled op is not necessarily 1:1—for example: things like AMP + // likely insert casts between tensor operations. + pub tensor_id: Option, + #[cfg(not(feature = "debug"))] + pub debug_buffer: Option>, #[cfg(feature = "debug")] pub debug_buffer: Option<(TensorId, Arc)>, #[cfg(feature = "debug")] diff --git a/crates/ratchet-core/src/cpu/binary.rs b/crates/ratchet-core/src/cpu/binary.rs index 146d80f4..b927fa61 100644 --- a/crates/ratchet-core/src/cpu/binary.rs +++ b/crates/ratchet-core/src/cpu/binary.rs @@ -2,6 +2,7 @@ use crate::cpu::cpu_store_result; use crate::{Binary, BinaryOp, CPUOperation, DType, OperationError, Tensor, TensorDType}; use core::marker::PhantomData; use half::{bf16, f16}; +use maybe_async::maybe_async; use num_traits::NumOps; #[inline] @@ -32,14 +33,15 @@ pub(crate) fn binary_map_inplace(lhs: &mut [T], rhs: &[T], f: fn } #[inline] -pub(crate) fn binary_apply( +#[maybe_async] +pub(crate) async fn binary_apply( lhs: &Tensor, rhs: &Tensor, dst: &Tensor, f: fn(T, T) -> U, ) -> Result<(), OperationError> { - let lhs = lhs.to_vec::()?; - let rhs = rhs.to_vec::()?; + let lhs = lhs.to_vec::().await?; + let rhs = rhs.to_vec::().await?; let mut result = vec![U::zero(); dst.shape().numel()]; binary_map(&lhs, &rhs, &mut result, f); cpu_store_result(dst, &result); @@ -47,14 +49,15 @@ pub(crate) fn binary_apply( } #[inline] -pub(crate) fn binary_apply_inplace( +#[maybe_async] +pub(crate) async fn binary_apply_inplace( lhs: &Tensor, rhs: &Tensor, dst: &Tensor, f: fn(T, T) -> T, ) -> Result<(), OperationError> { - let mut lhs = lhs.to_vec::()?; - let rhs = rhs.to_vec::()?; + let mut lhs = lhs.to_vec::().await?; + let rhs = rhs.to_vec::().await?; binary_map_inplace(&mut lhs, &rhs, f); cpu_store_result(dst, &lhs); Ok(()) @@ -66,8 +69,13 @@ pub struct BinaryOps { macro_rules! impl_cpu_binary_op { ($method_name:ident, $dtype:ident, $op:expr) => { - fn $method_name(lhs: &Tensor, rhs: &Tensor, dst: Tensor) -> Result { - binary_apply_inplace::<$dtype>(lhs, rhs, &dst, $op)?; + #[maybe_async] + async fn $method_name( + lhs: &Tensor, + rhs: &Tensor, + dst: Tensor, + ) -> Result { + binary_apply_inplace::<$dtype>(lhs, rhs, &dst, $op).await?; Ok(dst) } }; @@ -95,24 +103,28 @@ macro_rules! impl_cpu_binary { impl_cpu_binary_op!(mul, $dtype, |lhs, rhs| lhs * rhs); impl_cpu_binary_op!(div, $dtype, |lhs, rhs| lhs / rhs); - pub fn apply(op: &Binary, dst: Tensor) -> Result { + #[maybe_async] + pub async fn apply(op: &Binary, dst: Tensor) -> Result { match op.op() { - BinaryOp::Add => Self::add(op.lhs(), op.rhs(), dst), - BinaryOp::Sub => Self::sub(op.lhs(), op.rhs(), dst), - BinaryOp::Mul => Self::mul(op.lhs(), op.rhs(), dst), - BinaryOp::Div => Self::div(op.lhs(), op.rhs(), dst), + BinaryOp::Add => Self::add(op.lhs(), op.rhs(), dst).await, + BinaryOp::Sub => Self::sub(op.lhs(), op.rhs(), dst).await, + BinaryOp::Mul => Self::mul(op.lhs(), op.rhs(), dst).await, + BinaryOp::Div => Self::div(op.lhs(), op.rhs(), dst).await, } } } }; } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Binary { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match dst.dt() { - DType::F32 => BinaryOps::::apply(self, dst), - DType::F16 => BinaryOps::::apply(self, dst), - DType::BF16 => BinaryOps::::apply(self, dst), + DType::F32 => BinaryOps::::apply(self, dst).await, + DType::F16 => BinaryOps::::apply(self, dst).await, + DType::BF16 => BinaryOps::::apply(self, dst).await, _ => todo!(), } } diff --git a/crates/ratchet-core/src/cpu/gemm.rs b/crates/ratchet-core/src/cpu/gemm.rs index b932b37b..6e68ea34 100644 --- a/crates/ratchet-core/src/cpu/gemm.rs +++ b/crates/ratchet-core/src/cpu/gemm.rs @@ -6,6 +6,7 @@ use anyhow::{anyhow, Result}; use core::str::FromStr; use gemm::{gemm as gemm_kernel, Parallelism}; use half::{bf16, f16}; +use maybe_async::maybe_async; use std::num::NonZeroUsize; fn get_num_threads() -> NonZeroUsize { @@ -155,16 +156,20 @@ fn gemm_impl( ) } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Matmul { - fn apply_cpu(&self, dst: Tensor) -> Result { - fn run_gemm( + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn run_gemm( spec: MatmulSpec, lhs: &Tensor, rhs: &Tensor, dst: &Tensor, ) -> Result<(), OperationError> { - let lhs = lhs.to_vec::()?; - let rhs = rhs.to_vec::()?; + let lhs = lhs.to_vec::().await?; + let rhs = rhs.to_vec::().await?; let result = if spec.trans_dst() { gemm_impl::(spec, &rhs, &lhs)? @@ -179,9 +184,9 @@ impl CPUOperation for Matmul { let Matmul { lhs, rhs, .. } = self; match self.lhs.dt() { - DType::F32 => run_gemm::(spec, lhs, rhs, &dst), - DType::F16 => run_gemm::(spec, lhs, rhs, &dst), - DType::BF16 => run_gemm::(spec, lhs, rhs, &dst), + DType::F32 => run_gemm::(spec, lhs, rhs, &dst).await, + DType::F16 => run_gemm::(spec, lhs, rhs, &dst).await, + DType::BF16 => run_gemm::(spec, lhs, rhs, &dst).await, dtype => Err(InvariantError::UnsupportedDType(dtype))?, }?; Ok(dst) diff --git a/crates/ratchet-core/src/cpu/mod.rs b/crates/ratchet-core/src/cpu/mod.rs index 67c6f370..fed802dc 100644 --- a/crates/ratchet-core/src/cpu/mod.rs +++ b/crates/ratchet-core/src/cpu/mod.rs @@ -13,27 +13,29 @@ use crate::{ }; use anyhow::anyhow; use half::{bf16, f16}; +use maybe_async::maybe_async; use rope::cpu_rope; use unary::unary_apply_fn; use utils::cpu_store_result; -pub fn apply_operation(op: LazyOp, dst: Tensor) -> Result { +#[maybe_async] +pub async fn apply_operation(op: LazyOp, dst: Tensor) -> Result { match op { - LazyOp::Binary(b) => b.apply_cpu(dst), - LazyOp::Cast(c) => cpu_cast(c, dst), - LazyOp::Matmul(m) => m.apply_cpu(dst), - LazyOp::Softmax(s) => s.apply_cpu(dst), - LazyOp::RoPE(r) => cpu_rope(r, dst), + LazyOp::Binary(b) => b.apply_cpu(dst).await, + LazyOp::Cast(c) => cpu_cast(c, dst).await, + LazyOp::Matmul(m) => m.apply_cpu(dst).await, + LazyOp::Softmax(s) => s.apply_cpu(dst).await, + LazyOp::RoPE(r) => cpu_rope(r, dst).await, LazyOp::Alibi(a) => todo!(), - LazyOp::Unary(u) => u.apply_cpu(dst), - LazyOp::Reindex(r) => r.apply_cpu(dst), - LazyOp::Concat(c) => cpu_concat(c, dst), - LazyOp::Norm(n) => n.apply_cpu(dst), + LazyOp::Unary(u) => u.apply_cpu(dst).await, + LazyOp::Reindex(r) => r.apply_cpu(dst).await, + LazyOp::Concat(c) => cpu_concat(c, dst).await, + LazyOp::Norm(n) => n.apply_cpu(dst).await, LazyOp::Affine(_a) => todo!(), LazyOp::Cmp(_c) => todo!(), LazyOp::Powf(_p) => todo!(), LazyOp::Conv(_c) => todo!(), - LazyOp::Select(i) => cpu_index_select(i, dst), + LazyOp::Select(i) => cpu_index_select(i, dst).await, LazyOp::IndexWrite(_i) => todo!(), LazyOp::Cache(_c) => todo!(), LazyOp::Trilu(_t) => todo!(), @@ -44,6 +46,7 @@ pub fn apply_operation(op: LazyOp, dst: Tensor) -> Result todo!(), LazyOp::FillConstant(_f) => todo!(), LazyOp::FillRandn(_f) => todo!(), + LazyOp::Bernoulli(_b) => todo!(), LazyOp::Arange(_a) => todo!(), LazyOp::IndexAdd(_i) => todo!(), LazyOp::ScatterAdd(_s) => todo!(), @@ -52,11 +55,14 @@ pub fn apply_operation(op: LazyOp, dst: Tensor) -> Result Result; + async fn apply_cpu(&self, dst: Tensor) -> Result; } -fn index_select( +#[maybe_async] +async fn index_select( index_select: IndexSelect, dst: Tensor, ) -> Result { @@ -84,8 +90,8 @@ fn index_select( let left_len: usize = dst_dims[..dim].iter().product(); let right_len: usize = dst_dims[dim + 1..].iter().product(); - let src = src.to_vec::()?; - let indices = indices.to_vec::()?; + let src = src.to_vec::().await?; + let indices = indices.to_vec::().await?; let mut result = vec![T::zero(); dst_len]; for left_i in 0..left_len { @@ -102,67 +108,77 @@ fn index_select( Ok(dst) } -fn qindex_select(op: IndexSelect, dst: Tensor) -> Result { +#[maybe_async] +async fn qindex_select(op: IndexSelect, dst: Tensor) -> Result { // NOTE: qindex_select is functional but not optimized at all. // Currently we simply dequantize the entire input tensor to f32 and then call index_select. // Because of borrowing rules dequantizing also requires a deep clone of the input tensor, which is less than ideal. // In the future we would rather directly index the raw buffer of the quantized tensor and dequantize only what is required. // TODO: Add support for direct indexing + partial dequantization - let src = op.src().deep_clone(); + let src = op.src().deep_clone().await; // NOTE: Support for other quantization types is dependent on the corresponding dequantization functions. let src = dequantize(src); let indices = op.indices().clone(); let dim = op.dim(); - index_select::(IndexSelect::new(src, indices, dim), dst) + index_select::(IndexSelect::new(src, indices, dim), dst).await } -pub fn cpu_index_select(i: IndexSelect, dst: Tensor) -> Result { +#[maybe_async] +pub async fn cpu_index_select(i: IndexSelect, dst: Tensor) -> Result { match i.src().dt() { - DType::F32 => index_select::(i, dst), - DType::F16 => index_select::(i, dst), - DType::BF16 => index_select::(i, dst), - DType::Q8_0F(_) => qindex_select(i, dst), + DType::F32 => index_select::(i, dst).await, + DType::F16 => index_select::(i, dst).await, + DType::BF16 => index_select::(i, dst).await, + DType::Q8_0F(_) => qindex_select(i, dst).await, dtype => Err(InvariantError::UnsupportedDType(dtype).into()), } } -fn direct_cast( +#[maybe_async] +async fn direct_cast( input: &Tensor, dst: &Tensor, ) -> Result<(), OperationError> { - let input = input.to_vec::()?; + let input = input.to_vec::().await?; let result = bytemuck::try_cast_slice::(&input).map_err(|_| anyhow!("Failed direct cast"))?; cpu_store_result(dst, result); Ok(()) } -pub fn cpu_cast(cast: Cast, dst: Tensor) -> Result { +#[maybe_async] +pub async fn cpu_cast(cast: Cast, dst: Tensor) -> Result { if cast.input().dt() == cast.dst_dt() { return Ok(cast.input().clone()); } match (cast.input().dt(), cast.dst_dt()) { // F32 -> - (DType::F32, DType::F16) => unary_apply_fn::(cast.input(), &dst, f16::from_f32)?, + (DType::F32, DType::F16) => { + unary_apply_fn::(cast.input(), &dst, f16::from_f32).await? + } (DType::F32, DType::BF16) => { - unary_apply_fn::(cast.input(), &dst, bf16::from_f32)? + unary_apply_fn::(cast.input(), &dst, bf16::from_f32).await? } - (DType::F32, DType::I32) => direct_cast::(cast.input(), &dst)?, - (DType::F32, DType::U32) => direct_cast::(cast.input(), &dst)?, + (DType::F32, DType::I32) => direct_cast::(cast.input(), &dst).await?, + (DType::F32, DType::U32) => direct_cast::(cast.input(), &dst).await?, // F16 -> - (DType::F16, DType::F32) => unary_apply_fn::(cast.input(), &dst, f32::from)?, + (DType::F16, DType::F32) => { + unary_apply_fn::(cast.input(), &dst, f32::from).await? + } // BF16 -> - (DType::BF16, DType::F32) => unary_apply_fn::(cast.input(), &dst, f32::from)?, + (DType::BF16, DType::F32) => { + unary_apply_fn::(cast.input(), &dst, f32::from).await? + } // I32 -> - (DType::I32, DType::F32) => direct_cast::(cast.input(), &dst)?, + (DType::I32, DType::F32) => direct_cast::(cast.input(), &dst).await?, // U32 -> - (DType::U32, DType::F32) => direct_cast::(cast.input(), &dst)?, + (DType::U32, DType::F32) => direct_cast::(cast.input(), &dst).await?, _ => unimplemented!("Cannot cast {:?} -> {:?}", cast.input().dt(), cast.dst_dt()), }; @@ -195,7 +211,9 @@ pub(crate) fn concat( } Ok(()) } -pub(crate) fn apply_concat( + +#[maybe_async] +pub(crate) async fn apply_concat( inputs: RVec, dim: usize, dst: Tensor, @@ -203,24 +221,33 @@ pub(crate) fn apply_concat( let dst_size = dst.shape().numel(); let mut result = vec![T::zero(); dst_size]; - let inputs = inputs - .iter() - .map(|t| match t.to_vec::() { + let mut inputs_result = Vec::with_capacity(inputs.len()); + for t in inputs.iter() { + let result = match t.to_vec::().await { Ok(v) => Ok((t.shape().clone(), v)), Err(e) => Err(e.into()), - }) - .collect::, OperationError>>(); + }; + if let Err(e) = result { + return Err(e); + } + inputs_result.push(result.unwrap()); + } + let inputs = inputs_result; - concat(&inputs?, dim, dst.shape(), &mut result)?; + concat(&inputs, dim, dst.shape(), &mut result)?; cpu_store_result(&dst, &result); Ok(dst) } -pub fn cpu_concat(Concat { inputs, dim }: Concat, dst: Tensor) -> Result { +#[maybe_async] +pub async fn cpu_concat( + Concat { inputs, dim }: Concat, + dst: Tensor, +) -> Result { match dst.dt() { - DType::F32 => apply_concat::(inputs, dim, dst), - DType::F16 => apply_concat::(inputs, dim, dst), - DType::BF16 => apply_concat::(inputs, dim, dst), + DType::F32 => apply_concat::(inputs, dim, dst).await, + DType::F16 => apply_concat::(inputs, dim, dst).await, + DType::BF16 => apply_concat::(inputs, dim, dst).await, dtype => Err(InvariantError::UnsupportedDType(dtype).into()), } } diff --git a/crates/ratchet-core/src/cpu/norm.rs b/crates/ratchet-core/src/cpu/norm.rs index ce3389ab..27b8e1de 100644 --- a/crates/ratchet-core/src/cpu/norm.rs +++ b/crates/ratchet-core/src/cpu/norm.rs @@ -9,20 +9,25 @@ use crate::{ }; use core::iter::Sum; use half::{bf16, f16}; +use maybe_async::maybe_async; use num::Float; use num_traits::NumOps; +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for NormOp { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match self { - NormOp::LayerNorm(n) => apply_layer_norm(n, dst), - NormOp::RMSNorm(n) => apply_rms_norm(n, dst), - NormOp::GroupNorm(g) => apply_group_norm(g, dst), + NormOp::LayerNorm(n) => apply_layer_norm(n, dst).await, + NormOp::RMSNorm(n) => apply_rms_norm(n, dst).await, + NormOp::GroupNorm(g) => apply_group_norm(g, dst).await, } } } -fn apply_layer_norm( +#[maybe_async] +async fn apply_layer_norm( Norm { input, scale, @@ -49,9 +54,9 @@ fn apply_layer_norm( } match input.dt() { - DType::F32 => layer_norm::(input, scale, bias, *eps, &dst)?, - DType::F16 => layer_norm::(input, scale, bias, *eps, &dst)?, - DType::BF16 => layer_norm::(input, scale, bias, *eps, &dst)?, + DType::F32 => layer_norm::(input, scale, bias, *eps, &dst).await?, + DType::F16 => layer_norm::(input, scale, bias, *eps, &dst).await?, + DType::BF16 => layer_norm::(input, scale, bias, *eps, &dst).await?, _ => todo!(), }; @@ -88,7 +93,8 @@ where result } -fn layer_norm( +#[maybe_async] +async fn layer_norm( input: &Tensor, scale: &Tensor, bias: &Option, @@ -103,10 +109,10 @@ where let N = src_shape[rank - 1]; let norm_shape = shape!(N); - let input = input.to_vec::()?; - let scale = scale.to_vec::()?; + let input = input.to_vec::().await?; + let scale = scale.to_vec::().await?; let bias = match bias { - Some(b) => Some(b.to_vec::()?), + Some(b) => Some(b.to_vec::().await?), None => None, }; @@ -146,7 +152,8 @@ where Ok(()) } -fn apply_rms_norm( +#[maybe_async] +async fn apply_rms_norm( Norm { input, scale, @@ -173,16 +180,22 @@ fn apply_rms_norm( } match input.dt() { - DType::F32 => rms_norm::(input, scale, *eps, &dst)?, - DType::F16 => rms_norm::(input, scale, *eps, &dst)?, - DType::BF16 => rms_norm::(input, scale, *eps, &dst)?, + DType::F32 => rms_norm::(input, scale, *eps, &dst).await?, + DType::F16 => rms_norm::(input, scale, *eps, &dst).await?, + DType::BF16 => rms_norm::(input, scale, *eps, &dst).await?, _ => todo!(), }; Ok(dst) } -fn rms_norm(input: &Tensor, scale: &Tensor, eps: f32, dst: &Tensor) -> Result<(), OperationError> +#[maybe_async] +async fn rms_norm( + input: &Tensor, + scale: &Tensor, + eps: f32, + dst: &Tensor, +) -> Result<(), OperationError> where T: TensorDType + Float + NumOps + for<'a> Sum<&'a T>, { @@ -190,8 +203,8 @@ where let rank = input.rank(); let N = src_shape[rank - 1]; - let mut x = input.to_vec::()?; - let scale = scale.to_vec::()?; + let mut x = input.to_vec::().await?; + let scale = scale.to_vec::().await?; let mut x2 = x.clone(); square(&mut x2); @@ -212,7 +225,8 @@ where Ok(()) } -fn apply_group_norm(_n: &GroupNorm, dst: Tensor) -> Result { +#[maybe_async] +async fn apply_group_norm(_n: &GroupNorm, dst: Tensor) -> Result { //let result = norm(&b.src.to_vec::()?, b.src.shape(), b.to()); //cpu_store_result(&dst, &result); Ok(dst) diff --git a/crates/ratchet-core/src/cpu/reindex.rs b/crates/ratchet-core/src/cpu/reindex.rs index 3f33425e..db7089aa 100644 --- a/crates/ratchet-core/src/cpu/reindex.rs +++ b/crates/ratchet-core/src/cpu/reindex.rs @@ -4,34 +4,42 @@ use crate::{ Tensor, TensorDType, }; use half::{bf16, f16}; +use maybe_async::maybe_async; +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Reindex { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match self { - Reindex::Permute(p) => p.apply_cpu(dst), - Reindex::Slice(s) => s.apply_cpu(dst), - Reindex::Broadcast(b) => b.apply_cpu(dst), + Reindex::Permute(p) => p.apply_cpu(dst).await, + Reindex::Slice(s) => s.apply_cpu(dst).await, + Reindex::Broadcast(b) => b.apply_cpu(dst).await, } } } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Permute { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match dst.dt() { - DType::F32 => apply_permute::(self, dst), - DType::BF16 => apply_permute::(self, dst), - DType::F16 => apply_permute::(self, dst), - DType::I32 => apply_permute::(self, dst), - DType::U32 => apply_permute::(self, dst), + DType::F32 => apply_permute::(self, dst).await, + DType::BF16 => apply_permute::(self, dst).await, + DType::F16 => apply_permute::(self, dst).await, + DType::I32 => apply_permute::(self, dst).await, + DType::U32 => apply_permute::(self, dst).await, _ => todo!(), } } } -fn apply_permute(p: &Permute, dst: Tensor) -> Result { +#[maybe_async] +async fn apply_permute(p: &Permute, dst: Tensor) -> Result { let perm: [usize; 4] = p.promote().as_slice().try_into().unwrap(); let Permute { src, dims: _ } = p; - let result = permute(&src.to_vec::()?, src.shape(), dst.shape(), perm); + let result = permute(&src.to_vec::().await?, src.shape(), dst.shape(), perm); cpu_store_result(&dst, &result); Ok(dst) } @@ -70,22 +78,26 @@ fn permute( result } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Slice { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match dst.dt() { - DType::F32 => apply_slice::(self, dst), - DType::BF16 => apply_slice::(self, dst), - DType::F16 => apply_slice::(self, dst), - DType::I32 => apply_slice::(self, dst), - DType::U32 => apply_slice::(self, dst), + DType::F32 => apply_slice::(self, dst).await, + DType::BF16 => apply_slice::(self, dst).await, + DType::F16 => apply_slice::(self, dst).await, + DType::I32 => apply_slice::(self, dst).await, + DType::U32 => apply_slice::(self, dst).await, _ => todo!(), } } } -fn apply_slice(s: &Slice, dst: Tensor) -> Result { +#[maybe_async] +async fn apply_slice(s: &Slice, dst: Tensor) -> Result { let (start, stop): (Vec<_>, Vec<_>) = s.indices().iter().map(|r| (r.start, r.end)).unzip(); - let result = slice(&s.src.to_vec::()?, s.src.strides(), &start, &stop); + let result = slice(&s.src.to_vec::().await?, s.src.strides(), &start, &stop); cpu_store_result(&dst, &result); Ok(dst) @@ -127,21 +139,28 @@ pub(crate) fn slice( dst } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Broadcast { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match dst.dt() { - DType::F32 => apply_broadcast::(self, dst), - DType::BF16 => apply_broadcast::(self, dst), - DType::F16 => apply_broadcast::(self, dst), - DType::I32 => apply_broadcast::(self, dst), - DType::U32 => apply_broadcast::(self, dst), + DType::F32 => apply_broadcast::(self, dst).await, + DType::BF16 => apply_broadcast::(self, dst).await, + DType::F16 => apply_broadcast::(self, dst).await, + DType::I32 => apply_broadcast::(self, dst).await, + DType::U32 => apply_broadcast::(self, dst).await, _ => todo!(), } } } -fn apply_broadcast(b: &Broadcast, dst: Tensor) -> Result { - let result = broadcast(&b.src.to_vec::()?, b.src.shape(), b.to()); +#[maybe_async] +async fn apply_broadcast( + b: &Broadcast, + dst: Tensor, +) -> Result { + let result = broadcast(&b.src.to_vec::().await?, b.src.shape(), b.to()); cpu_store_result(&dst, &result); Ok(dst) } diff --git a/crates/ratchet-core/src/cpu/rope.rs b/crates/ratchet-core/src/cpu/rope.rs index a1d407f0..bc50d96b 100644 --- a/crates/ratchet-core/src/cpu/rope.rs +++ b/crates/ratchet-core/src/cpu/rope.rs @@ -3,14 +3,16 @@ use crate::{ cpu::{cpu_store_result, gemm::gemm, reindex::slice}, shape, DType, OperationError, RoPE, Shape, Strides, Tensor, }; +use maybe_async::maybe_async; -pub fn cpu_rope(op: RoPE, dst: Tensor) -> Result { +#[maybe_async] +pub async fn cpu_rope(op: RoPE, dst: Tensor) -> Result { match op.input().dt() { DType::F32 => { let dim = op.dim(); let base = op.base(); let offset = op.offset(); - let src = op.input().to_vec::()?; + let src = op.input().to_vec::().await?; let result = rope(src, op.input().shape(), dim, base, offset)?; cpu_store_result(&dst, &result) } diff --git a/crates/ratchet-core/src/cpu/softmax.rs b/crates/ratchet-core/src/cpu/softmax.rs index 1d6a3df0..d4aafa54 100644 --- a/crates/ratchet-core/src/cpu/softmax.rs +++ b/crates/ratchet-core/src/cpu/softmax.rs @@ -1,16 +1,20 @@ use crate::cpu::utils::cpu_store_result; use crate::{CPUOperation, DType, OperationError, Softmax, Tensor, TensorDType}; use half::{bf16, f16}; +use maybe_async::maybe_async; use num::Float; use num_traits::NumAssignOps; +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Softmax { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { let Softmax { input, dim } = self; match input.dt() { - DType::F32 => softmax::(input, *dim, &dst)?, - DType::F16 => softmax::(input, *dim, &dst)?, - DType::BF16 => softmax::(input, *dim, &dst)?, + DType::F32 => softmax::(input, *dim, &dst).await?, + DType::F16 => softmax::(input, *dim, &dst).await?, + DType::BF16 => softmax::(input, *dim, &dst).await?, _ => todo!(), } @@ -18,12 +22,13 @@ impl CPUOperation for Softmax { } } -fn softmax(input: &Tensor, dim: usize, dst: &Tensor) -> Result<(), OperationError> +#[maybe_async] +async fn softmax(input: &Tensor, dim: usize, dst: &Tensor) -> Result<(), OperationError> where T: TensorDType + Float + NumAssignOps, { let src_shape = input.shape(); - let mut input = input.to_vec::()?; + let mut input = input.to_vec::().await?; let N = src_shape[dim]; input.chunks_mut(N).for_each(|chunk| { let mut sum = T::zero(); diff --git a/crates/ratchet-core/src/cpu/unary.rs b/crates/ratchet-core/src/cpu/unary.rs index 54271b30..0554757f 100644 --- a/crates/ratchet-core/src/cpu/unary.rs +++ b/crates/ratchet-core/src/cpu/unary.rs @@ -2,6 +2,7 @@ use crate::cpu::cpu_store_result; use crate::{CPUOperation, DType, OperationError, Tensor, TensorDType, Unary, UnaryOp}; use core::marker::PhantomData; use half::{bf16, f16}; +use maybe_async::maybe_async; use num_traits::Float; #[inline] @@ -24,12 +25,13 @@ pub(crate) fn unary_map_inplace(src: &mut [T], f: fn(T) -> T) { } #[inline] -pub(crate) fn unary_apply_fn( +#[maybe_async] +pub(crate) async fn unary_apply_fn( input: &Tensor, dst: &Tensor, f: fn(T) -> U, ) -> Result<(), OperationError> { - let input = input.to_vec::()?; + let input = input.to_vec::().await?; let mut result = vec![U::zero(); dst.shape().numel()]; unary_apply_fn_helper(&input, &mut result, f); cpu_store_result(dst, &result); @@ -70,26 +72,27 @@ macro_rules! impl_unary_ops { * x * ($conv(1.0) / ($conv(1.0) + (-x).exp()))); - fn apply(op: &Unary, dst: Tensor) -> Result { + #[maybe_async] + async fn apply(op: &Unary, dst: Tensor) -> Result { match op.op() { - UnaryOp::Gelu => Self::gelu(op.input(), dst), - UnaryOp::Tanh => Self::tanh(op.input(), dst), - UnaryOp::Exp => Self::exp(op.input(), dst), - UnaryOp::Log => Self::log(op.input(), dst), - UnaryOp::Sin => Self::sin(op.input(), dst), - UnaryOp::Cos => Self::cos(op.input(), dst), - UnaryOp::Abs => Self::abs(op.input(), dst), - UnaryOp::Square => Self::square(op.input(), dst), - UnaryOp::Sqrt => Self::sqrt(op.input(), dst), - UnaryOp::Relu => Self::relu(op.input(), dst), - UnaryOp::Relu2 => Self::relu2(op.input(), dst), - UnaryOp::Floor => Self::floor(op.input(), dst), - UnaryOp::Ceil => Self::ceil(op.input(), dst), - UnaryOp::Neg => Self::neg(op.input(), dst), - UnaryOp::Reciprocal => Self::reciprocal(op.input(), dst), - UnaryOp::Silu => Self::silu(op.input(), dst), - UnaryOp::Sigmoid => Self::sigmoid(op.input(), dst), - UnaryOp::Swiglu => Self::swiglu(op.input(), dst), + UnaryOp::Gelu => Self::gelu(op.input(), dst).await, + UnaryOp::Tanh => Self::tanh(op.input(), dst).await, + UnaryOp::Exp => Self::exp(op.input(), dst).await, + UnaryOp::Log => Self::log(op.input(), dst).await, + UnaryOp::Sin => Self::sin(op.input(), dst).await, + UnaryOp::Cos => Self::cos(op.input(), dst).await, + UnaryOp::Abs => Self::abs(op.input(), dst).await, + UnaryOp::Square => Self::square(op.input(), dst).await, + UnaryOp::Sqrt => Self::sqrt(op.input(), dst).await, + UnaryOp::Relu => Self::relu(op.input(), dst).await, + UnaryOp::Relu2 => Self::relu2(op.input(), dst).await, + UnaryOp::Floor => Self::floor(op.input(), dst).await, + UnaryOp::Ceil => Self::ceil(op.input(), dst).await, + UnaryOp::Neg => Self::neg(op.input(), dst).await, + UnaryOp::Reciprocal => Self::reciprocal(op.input(), dst).await, + UnaryOp::Silu => Self::silu(op.input(), dst).await, + UnaryOp::Sigmoid => Self::sigmoid(op.input(), dst).await, + UnaryOp::Swiglu => Self::swiglu(op.input(), dst).await, } } } @@ -98,19 +101,23 @@ macro_rules! impl_unary_ops { macro_rules! impl_cpu_unary_op { ($method_name:ident, $op:expr) => { - fn $method_name(input: &Tensor, dst: Tensor) -> Result { - unary_apply_fn(input, &dst, $op)?; + #[maybe_async] + async fn $method_name(input: &Tensor, dst: Tensor) -> Result { + unary_apply_fn(input, &dst, $op).await?; Ok(dst) } }; } +#[maybe_async(AFIT)] +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] impl CPUOperation for Unary { - fn apply_cpu(&self, dst: Tensor) -> Result { + #[maybe_async] + async fn apply_cpu(&self, dst: Tensor) -> Result { match dst.dt() { - DType::F32 => UnaryOps::::apply(self, dst), - DType::F16 => UnaryOps::::apply(self, dst), - DType::BF16 => UnaryOps::::apply(self, dst), + DType::F32 => UnaryOps::::apply(self, dst).await, + DType::F16 => UnaryOps::::apply(self, dst).await, + DType::BF16 => UnaryOps::::apply(self, dst).await, _ => todo!(), } } @@ -118,7 +125,7 @@ impl CPUOperation for Unary { macro_rules! impl_cpu_unary { ($dtype:ident) => { - impl_cpu_unary!($dtype, |x| x); + impl_cpu_unary!($dtype, |x: $dtype| -> $dtype { x }); }; ($dtype:ident, $conv:expr) => { impl_unary_ops!($dtype, $conv); diff --git a/crates/ratchet-core/src/executable.rs b/crates/ratchet-core/src/executable.rs index 150c8eda..8f1fbae3 100644 --- a/crates/ratchet-core/src/executable.rs +++ b/crates/ratchet-core/src/executable.rs @@ -1,21 +1,26 @@ use crate::gpu::{GpuUniform, PoolError, StaticResourcePoolAccessor, WgpuDevice}; -use crate::{Compiled, Storage}; +use crate::{ + Compiled, CompiledCopy, CompiledOp, ExportedTensorProfilingEntry, HashMap, StepLogConfig, + Storage, TensorId, +}; + // #[cfg(feature = "debug")] (for tensor?) +use crate::gpu::Profiler; use crate::Tensor; #[cfg(feature = "debug")] -use crate::{CPUBuffer, DType, HashMap, TensorId}; +use crate::{DType, HashMap, TensorId}; #[cfg(feature = "debug")] +use crate::{DeviceStorage, KernelKey, RVec}; +use derive_new::new; use maybe_async::maybe_async; #[cfg(feature = "debug")] use parking_lot::RwLock; #[cfg(feature = "debug")] use slotmap::Key; -#[cfg(feature = "debug")] +#[cfg(not(feature = "debug"))] +use std::collections::BTreeMap; +use std::iter::Peekable; use std::sync::Arc; - -#[cfg(feature = "debug")] -use crate::{wgpu_buffer_to_cpu_buffer, DeviceStorage, KernelKey, RVec}; -use derive_new::new; use wgpu::SubmissionIndex; #[cfg(feature = "debug")] @@ -36,6 +41,8 @@ pub struct Executable { storage: Option>>, pub(crate) steps: Vec, gpu_uniform: GpuUniform, + #[cfg(not(feature = "debug"))] + pub(crate) debug_list: Option>, #[cfg(feature = "debug")] pub(crate) debug_list: Option>, #[cfg(feature = "debug")] @@ -51,83 +58,212 @@ pub enum ExecutionError { DebuggingError(&'static str), } +pub struct ExecutionResult { + pub profiling_entries: Option>, + pub gpu_bufs: Option>, +} + impl Executable { - #[cfg(not(feature = "gpu-profiling"))] - pub fn dispatch(&self, device: &WgpuDevice) -> Result { + // Helper function to set up pipeline and dispatch workgroups + #[inline] + fn compute_pass_inner<'a>( + compute_pass: &mut wgpu::ComputePass<'a>, + op: &CompiledOp, + pipeline_resources: &crate::StaticResourcePoolReadLockAccessor< + '_, + crate::ComputePipelineHandle, + wgpu::ComputePipeline, + >, + gpu_uniform: &GpuUniform, + ) -> Result<(), ExecutionError> { + compute_pass.set_pipeline(pipeline_resources.get(op.pipeline_handle())?); + for (group_index, bind_group) in op.storage_groups().iter().enumerate() { + compute_pass.set_bind_group(group_index as u32, bind_group, &[]); + } + let uniform_group_index = op.storage_groups().len() as u32; + let uniform_group = gpu_uniform.bind_group(); + compute_pass.set_bind_group(uniform_group_index, uniform_group, &[op.offset()]); + let [x_count, y_count, z_count] = op.workgroup_count().as_slice(); + compute_pass.dispatch_workgroups(x_count, y_count, z_count); + Ok(()) + } + + #[cfg(all(not(feature = "gpu-profiling"), not(feature = "debug")))] + #[maybe_async] + pub async fn dispatch( + &mut self, + device: &WgpuDevice, + step_log_config: Option<&StepLogConfig>, + ) -> Result<(SubmissionIndex, ExecutionResult), ExecutionError> { let pipeline_resources: crate::StaticResourcePoolReadLockAccessor< '_, crate::ComputePipelineHandle, wgpu::ComputePipeline, > = device.pipeline_resources(); + let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + Some(device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None })); + + #[inline] + fn create_timestamp_writes<'a>( + profiler: &'a mut Option, + op: &CompiledOp, + ) -> Option> { + if let Some(profiler) = profiler { + let label = format!("{}_{}", op.kernel_key, op.workgroup_count().to_string()); + if let Some(id) = op.tensor_id { + Some(profiler.create_timestamp_queries(id, label.as_str())) + } else { + None + } + } else { + None + } + } - // Create a peekable iterator over the steps. - let mut steps_iter = self.steps.iter().peekable(); + let compute_step_count = self + .steps + .iter() + .filter(|step| matches!(step, Compiled::Compute(_))) + .count(); + + let grouped_iter = GroupedIter::new(self.steps.iter_mut()); + + let mut profiler = step_log_config.as_ref().and_then(|config| { + config + .profiling + .then(|| Profiler::new(device.clone(), compute_step_count as _)) + }); + + // let mut debug_steps = vec![]; + let mut gpu_bufs: Option> = None; + + for group in grouped_iter { + match group { + GroupedOp::Compute(mut ops) => { + let mut cpass = None; + + let mut ops_iter = ops.iter_mut().peekable(); + while let Some(op) = ops_iter.next() { + let timestamp_writes = create_timestamp_writes(&mut profiler, op); + + // Existing compute pass; shared + if let Some(compute_pass) = cpass.as_mut() { + Self::compute_pass_inner( + compute_pass, + op, + &pipeline_resources, + &self.gpu_uniform, + )?; + } else { + // Create a new encoder if one doesn't exist already + if encoder.is_none() { + encoder = Some(device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + )); + } - while let Some(step) = steps_iter.next() { - match step { - Compiled::Compute(op) => { - // Start a new compute pass for contiguous compute operations. - let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { - label: Some("ratchet inference pass"), - timestamp_writes: None, - }); - - // Process the current compute operation. - cpass.set_pipeline(pipeline_resources.get(op.pipeline_handle())?); - for (group_index, bind_group) in op.storage_groups().iter().enumerate() { - cpass.set_bind_group(group_index as u32, bind_group, &[]); - } - let uniform_group_index = op.storage_groups().len() as u32; - let uniform_group = self.gpu_uniform.bind_group(); - cpass.set_bind_group(uniform_group_index, uniform_group, &[op.offset()]); - let [x_count, y_count, z_count] = op.workgroup_count().as_slice(); - cpass.dispatch_workgroups(x_count, y_count, z_count); + let mut new_cpass = encoder + .as_mut() + .unwrap() + .begin_compute_pass(&wgpu::ComputePassDescriptor { + label: None, + timestamp_writes, + }) + .forget_lifetime(); - // Consume all subsequent contiguous compute operations. - while let Some(next_step) = steps_iter.peek() { - if let Compiled::Compute(_) = next_step { - // Consume this step. - let next_op = if let Compiled::Compute(op) = steps_iter.next().unwrap() - { - op - } else { - unreachable!() - }; - - cpass.set_pipeline(pipeline_resources.get(next_op.pipeline_handle())?); - for (group_index, bind_group) in - next_op.storage_groups().iter().enumerate() - { - cpass.set_bind_group(group_index as u32, bind_group, &[]); - } - let uniform_group_index = next_op.storage_groups().len() as u32; - let uniform_group = self.gpu_uniform.bind_group(); - cpass.set_bind_group( - uniform_group_index, - uniform_group, - &[next_op.offset()], + Self::compute_pass_inner( + &mut new_cpass, + op, + &pipeline_resources, + &self.gpu_uniform, + )?; + + cpass = Some(new_cpass); + } + + if profiler.is_some() { + // In profile mode, we need to create a new cpass for each op + cpass = None; + } + + if let Some(debug_buffer) = op.debug_buffer.take() { + // Cpass needs to be dropped before we submit the encoder + cpass = None; + + let result_t = self + .debug_list + .as_ref() + .expect("Debug list is not set") + .get(&op.tensor_id.expect("Tensor id is not set")) + .expect("Tensor not found in debug list"); + + let gpu_storage = result_t.storage(); + let result_buf = &gpu_storage + .as_ref() + .ok_or(ExecutionError::DebuggingError("Failed to get result buf."))? + .try_gpu() + .map_err(|_| { + ExecutionError::DebuggingError("Result buf is not on GPU.") + })? + .inner; + + encoder.as_mut().unwrap().copy_buffer_to_buffer( + result_buf, + 0, + &debug_buffer, + 0, + result_t.num_bytes() as _, + ); + + gpu_bufs.get_or_insert_default().insert( + op.tensor_id.expect("Tensor id is not set"), + Arc::try_unwrap(debug_buffer).unwrap(), ); - let [x_count, y_count, z_count] = next_op.workgroup_count().as_slice(); - cpass.dispatch_workgroups(x_count, y_count, z_count); - } else { - break; } } - // The compute pass is automatically ended when `cpass` goes out of scope. } - Compiled::Copy(op) => { + GroupedOp::Copy(op) => { + // Create a new encoder if one doesn't exist already + if encoder.is_none() { + encoder = Some(device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + )); + } + // Process the copy operation outside of a compute pass. let src = op.src().as_ref(); let dst = op.dst().as_ref(); let size = op.size(); - encoder.copy_buffer_to_buffer(src, 0, dst, 0, size); + encoder + .as_mut() + .unwrap() + .copy_buffer_to_buffer(src, 0, dst, 0, size); } } } - Ok(device.queue().submit(Some(encoder.finish()))) + if let Some(profiler) = profiler.as_mut() { + profiler.resolve(encoder.as_mut().unwrap()); + } + + let index = device + .queue() + .submit(Some(encoder.take().unwrap().finish())); + + let profiling_entries = if let Some(profiler) = profiler { + Some(profiler.read_timestamps().await) + } else { + None + }; + + Ok(( + index, + ExecutionResult { + profiling_entries, + gpu_bufs, + }, + )) } #[cfg(feature = "debug")] @@ -152,26 +288,23 @@ impl Executable { while let Some((step_index, step)) = steps_iter.next() { match step { Compiled::Compute(op) => { - // Group contiguous compute operations. let mut compute_group = vec![(step_index, op)]; while let Some(&(next_index, next_step)) = steps_iter.peek() { if let Compiled::Compute(next_op) = next_step { compute_group.push((next_index, next_op)); - steps_iter.next(); // Consume the op. + steps_iter.next(); } else { break; } } for &(step_index, op) in &compute_group { - // Create a single encoder for the entire compute-group. let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None, }); { - // Begin a compute pass for all the grouped compute operations. let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: Some("ratchet inference pass"), @@ -191,20 +324,12 @@ impl Executable { .map(|e| e.handle.data()) .collect::>(), ); - cpass.set_pipeline(pipeline_resources.get(op.pipeline_handle())?); - for (group_index, bind_group) in op.storage_groups().iter().enumerate() - { - cpass.set_bind_group(group_index as u32, bind_group, &[]); - } - let uniform_group_index = op.storage_groups().len() as u32; - let uniform_group = self.gpu_uniform.bind_group(); - cpass.set_bind_group( - uniform_group_index, - uniform_group, - &[op.offset()], - ); - let [x_count, y_count, z_count] = op.workgroup_count().as_slice(); - cpass.dispatch_workgroups(x_count, y_count, z_count); + Self::compute_pass_inner( + &mut cpass, + op, + &pipeline_resources, + &self.gpu_uniform, + )?; } // Process the debugging copy operations associated with each compute op. @@ -393,46 +518,42 @@ impl Executable { while let Some(step) = steps_iter.next() { match step { Compiled::Compute(op) => { - // Group all contiguous compute operations. let mut compute_group = vec![op]; while let Some(next_step) = steps_iter.peek() { if let Compiled::Compute(next_op) = next_step { compute_group.push(next_op); - steps_iter.next(); // consume the op + // consume the op + steps_iter.next(); } else { break; } } - // Use the first op's label for the entire group. - let first_op = compute_group.first().unwrap(); - let group_label = format!( - "grouped: {} ({} ops)", - first_op.kernel_key, - compute_group.len() - ); - let timestamp_writes = - Some(profiler.create_timestamp_queries(0, group_label.as_str())); - - // Begin one compute pass for the grouped compute operations. - let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { - label: Some("ratchet inference pass"), - timestamp_writes, - }); for op in compute_group { + let label = + format!("{}_{}", op.kernel_key, op.workgroup_count().to_string()); + let timestamp_writes = + Some(profiler.create_timestamp_queries(0, label.as_str())); + let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { + label: None, + timestamp_writes, + }); cpass.set_pipeline(pipeline_resources.get(op.pipeline_handle())?); + for (group_index, bind_group) in op.storage_groups().iter().enumerate() { cpass.set_bind_group(group_index as u32, bind_group, &[]); } + let uniform_group_index = op.storage_groups().len() as u32; let uniform_group = self.gpu_uniform.bind_group(); cpass.set_bind_group(uniform_group_index, uniform_group, &[op.offset()]); + let [x_count, y_count, z_count] = op.workgroup_count().as_slice(); cpass.dispatch_workgroups(x_count, y_count, z_count); } } Compiled::Copy(op) => { - // Process copy operations individually. + // TODO(vinhowe): Decide on the best way to profile these? let mut encoder_copy = device .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); let src = op.src().as_ref(); @@ -446,7 +567,7 @@ impl Executable { profiler.resolve(&mut encoder); let index = device.queue().submit(Some(encoder.finish())); - profiler.read_timestamps(true); + profiler.print_timestamps(true); Ok(index) } @@ -483,6 +604,7 @@ impl Executable { storage: self.storage, steps: self.steps, gpu_uniform: self.gpu_uniform, + debug_list: None, #[cfg(feature = "debug")] debug_list: None, #[cfg(feature = "debug")] @@ -490,3 +612,56 @@ impl Executable { }) } } + +enum GroupedOp<'a> { + Compute(Vec<&'a mut CompiledOp>), + Copy(&'a mut CompiledCopy), +} + +struct GroupedIter<'a, I> +where + I: Iterator, +{ + iter: Peekable, +} + +impl<'a, I> GroupedIter<'a, I> +where + I: Iterator, +{ + fn new(iter: I) -> Self { + Self { + iter: iter.peekable(), + } + } +} + +impl<'a, I> Iterator for GroupedIter<'a, I> +where + I: Iterator, +{ + type Item = GroupedOp<'a>; + + fn next(&mut self) -> Option { + // Get the first item of the next group. + let first = self.iter.next()?; + match first { + Compiled::Compute(op) => { + let mut ops = vec![op]; + loop { + match self.iter.peek() { + // Group Compute operations + Some(Compiled::Compute(_)) => { + if let Some(Compiled::Compute(next_op)) = self.iter.next() { + ops.push(next_op); + } + } + _ => break, + } + } + Some(GroupedOp::Compute(ops)) + } + Compiled::Copy(op) => Some(GroupedOp::Copy(op)), + } + } +} diff --git a/crates/ratchet-core/src/gpu/buffer_allocator/allocator.rs b/crates/ratchet-core/src/gpu/buffer_allocator/allocator.rs index 907c6ea2..aafc74c7 100644 --- a/crates/ratchet-core/src/gpu/buffer_allocator/allocator.rs +++ b/crates/ratchet-core/src/gpu/buffer_allocator/allocator.rs @@ -409,25 +409,25 @@ impl BufferAllocator { assignments.insert(output.id(), output_buffer); } - #[cfg(debug_assertions)] - { - let mut output_allocations = BTreeMap::new(); - for t in execution_order.iter() { - if let Some(allocation) = assignments.get(&t.id()) { - if output_tensors.contains_key(&t.id()) { - output_allocations.insert(allocation.global_id(), t.id()); - } else if let Some(output_id) = output_allocations.get(&allocation.global_id()) - { - panic!( - "Allocation {:?} used by output tensor {:?} was reused by tensor {:?}", - allocation.global_id(), - output_id, - t.id() - ); - } - } - } - } + // #[cfg(debug_assertions)] + // { + // let mut output_allocations = BTreeMap::new(); + // for t in execution_order.iter() { + // if let Some(allocation) = assignments.get(&t.id()) { + // if output_tensors.contains_key(&t.id()) { + // output_allocations.insert(allocation.global_id(), t.id()); + // } else if let Some(output_id) = output_allocations.get(&allocation.global_id()) + // { + // panic!( + // "Allocation {:?} used by output tensor {:?} was reused by tensor {:?}", + // allocation.global_id(), + // output_id, + // t.id() + // ); + // } + // } + // } + // } log::debug!( "Total bytes allocated: {}kb", diff --git a/crates/ratchet-core/src/gpu/buffer_allocator/lazy_graph_executor.rs b/crates/ratchet-core/src/gpu/buffer_allocator/lazy_graph_executor.rs index b5660a13..c88d6034 100644 --- a/crates/ratchet-core/src/gpu/buffer_allocator/lazy_graph_executor.rs +++ b/crates/ratchet-core/src/gpu/buffer_allocator/lazy_graph_executor.rs @@ -1,13 +1,15 @@ use crate::{ - CpuUniform, Executable, ExecutionError, GPUBuffer, HashMap, HashSet, Hasher as HasherType, - Inner, LazyOp, Storage, TensorError, WgpuDevice, + reset_scope_context, BufferUsagesExt, Compiled, CpuUniform, DebugSelection, Executable, + ExecutionError, ExecutionResult, GPUBuffer, HashMap, HashSet, Hasher as HasherType, Inner, + LazyOp, StepLog, StepLogConfig, Storage, TensorError, WgpuDevice, }; #[cfg(feature = "debug")] use crate::{DebugTensor, Device, DeviceStorage}; use crate::{Tensor, TensorId}; +use maybe_async::maybe_async; use parking_lot::RwLock; use std::collections::BTreeMap; -use std::hash::{BuildHasherDefault, Hasher}; +use std::hash::Hasher; use std::sync::{Arc, Weak}; enum EmitStatus { @@ -20,14 +22,17 @@ type PostOrderData<'a> = Vec<&'a Tensor>; struct CachedExecutable { executable: Arc, - shared_realloc: bool, + is_shared_realloc: bool, } pub struct LazyGraphExecutor { tensors: Arc>>>, cache: HashMap, + step_log_config: Option, pass_index: u64, inplace_support: bool, + caching_enabled: bool, + shared_object_allocation_enabled: bool, } fn panic_cycle(id: TensorId) { @@ -92,12 +97,19 @@ fn compute_post_order_from_nodes(roots: Vec<&Tensor>) -> PostOrderData { } impl LazyGraphExecutor { - pub fn new(inplace_support: bool) -> Self { + pub fn new( + inplace_support: bool, + caching_enabled: bool, + shared_object_allocation_enabled: bool, + ) -> Self { Self { tensors: Arc::new(RwLock::new(BTreeMap::default())), cache: HashMap::default(), pass_index: Default::default(), inplace_support, + step_log_config: None, + caching_enabled, + shared_object_allocation_enabled, } } @@ -133,18 +145,22 @@ impl LazyGraphExecutor { compute_post_order_from_nodes(tensors) } - pub fn sync_live_tensors_graph( + #[maybe_async] + pub async fn sync_live_tensors_graph( &mut self, gpu_device: &WgpuDevice, ) -> anyhow::Result<(), TensorError> { + reset_scope_context(); log::trace!("Syncing live tensors graph"); let tensors = self.get_live_tensors(); log::debug!("All registered IDs: {:?}", self.tensors.read().keys()); let owned_tensors = tensors.keys().cloned().collect(); - self.sync_tensors_graph_impl(tensors, Some(owned_tensors), gpu_device, true) + self.sync_tensors_graph_impl(tensors, Some(owned_tensors), gpu_device) + .await } - pub fn sync_tensors_graph( + #[maybe_async] + pub async fn sync_tensors_graph( &mut self, tensors: Vec<&Tensor>, gpu_device: &WgpuDevice, @@ -153,35 +169,38 @@ impl LazyGraphExecutor { tensors.into_iter().map(|t| (t.id(), t.clone())).collect(), None, gpu_device, - false, ) + .await } - fn run_executable( + #[maybe_async] + async fn run_executable( &mut self, - executable: &Executable, + executable: &mut Executable, gpu_device: &WgpuDevice, immediate: bool, - ) -> anyhow::Result<(), ExecutionError> { + ) -> anyhow::Result { log::debug!("Running executable"); #[cfg(feature = "debug")] let index = executable.dispatch_debugging(gpu_device)?; #[cfg(not(feature = "debug"))] - let index = executable.dispatch(gpu_device)?; + let (index, result) = executable + .dispatch(gpu_device, self.step_log_config.as_ref()) + .await?; if immediate { gpu_device.poll(wgpu::MaintainBase::WaitForSubmissionIndex(index)); } - Ok(()) + Ok(result) } - fn sync_tensors_graph_impl( + #[maybe_async] + async fn sync_tensors_graph_impl( &mut self, tensors: BTreeMap, owned_tensors: Option>, gpu_device: &WgpuDevice, - use_cache: bool, ) -> Result<(), TensorError> { // First check if the tensors are already resolved log::debug!("Syncing tensors graph"); @@ -189,27 +208,24 @@ impl LazyGraphExecutor { return Ok(()); } + let use_cache = self.caching_enabled; + // Notably, we compute post order first because we want to hash the tensors in post order, // since each hash depends on the hashes of its sources. It's not clear to me that this // violates some important unspoken assumption on the part of the LazyTensor authors. // We also flip the hash order—post order first, then insertion order—because it's more // convenient to treat it as one big hash pass. // let tensors = tensors.clone(); - let post_order = self.run_post_order(tensors.values().collect()); + let combined_post_orders = self.run_post_order(tensors.values().collect()); let mut indices = Vec::with_capacity(tensors.len()); - let mut tensor_ids = HashSet::with_capacity_and_hasher( - tensors.len(), - BuildHasherDefault::::default(), - ); + let mut tensor_ids = HashSet::with_capacity_and_hasher(tensors.len(), Default::default()); let mut hasher = HasherType::default(); let mut tensor_hashes = BTreeMap::default(); - let mut consumed_tensors = HashSet::with_capacity_and_hasher( - tensors.len(), - BuildHasherDefault::::default(), - ); + // Keep track of tensors that have been used as an src by another tensor + let mut used_as_src = HashSet::with_capacity_and_hasher(tensors.len(), Default::default()); let mut uniform = CpuUniform::new(); let mut compile_keys = HashMap::default(); @@ -220,111 +236,124 @@ impl LazyGraphExecutor { // annoying views correctly. let mut tensor_sources = HashMap::default(); - // First we loop over the post order to hash the tensors in the right order - for tensor in &post_order { - // Scope to drop tensor_hashes before inserting - let srcs = tensor.op().srcs(); - log::trace!( - "{:?}: Srcs: {:?}", - tensor.id(), - srcs.iter().map(|s| s.id()).collect::>() - ); - let first_src = srcs.first().cloned(); - - let mut to_modify = None; - if !matches!(tensor.op(), LazyOp::View(_)) { - tensor_sources.insert(tensor.id(), tensor); - to_modify = first_src.map(|src| { - tensor_sources - .get(&src.id()) - .cloned() - .expect("Source missing entry in tensor_sources") - }); - } else if let Some(src) = tensor_sources - .get(&first_src.expect("All views should have one src").id()) - .cloned() - { - tensor_sources.insert(tensor.id(), src); - to_modify = Some(src); - } + let mut seen_nodes = HashSet::default(); + let mut post_order = Vec::new(); - let can_inplace = match to_modify { - Some(to_modify_src) => { - log::trace!( - "{:?}: Supports inplace: {:?}, is variable: {:?}", - tensor.id(), - tensor.op().supports_inplace(), - to_modify_src.is_variable() - ); + // First we loop over the post order to hash the tensors in the right order + for tensor in combined_post_orders.into_iter() { + if seen_nodes.insert(tensor.id()) { + post_order.push(tensor); + // Scope to drop tensor_hashes before inserting + let srcs = tensor.op().srcs(); + log::trace!( + "{:?}: Srcs: {:?}", + tensor.id(), + srcs.iter().map(|s| s.id()).collect::>() + ); + let first_src = srcs.first().cloned(); + + let mut to_modify = None; + if !matches!(tensor.op(), LazyOp::View(_)) { + tensor_sources.insert(tensor.id(), tensor); + to_modify = first_src.map(|src| { + tensor_sources + .get(&src.id()) + .cloned() + .expect("Source missing entry in tensor_sources") + }); + } else if let Some(src) = tensor_sources + .get(&first_src.expect("All views should have one src").id()) + .cloned() + { + tensor_sources.insert(tensor.id(), src); + to_modify = Some(src); + } - if !self.inplace_support { - match tensor.op() { - LazyOp::Softmax(_) | LazyOp::ScatterAdd(_) | LazyOp::IndexAdd(_) => { - true - } - LazyOp::Detach(d) => { - matches!( - d.as_ref(), - LazyOp::Softmax(_) - | LazyOp::ScatterAdd(_) - | LazyOp::IndexAdd(_) - ) + let can_inplace = match to_modify { + Some(to_modify_src) => { + log::trace!( + "{:?}: Supports inplace: {:?}, is variable: {:?}", + tensor.id(), + tensor.op().supports_inplace(), + to_modify_src.is_variable() + ); + + if !self.inplace_support { + match tensor.op() { + LazyOp::Softmax(_) + | LazyOp::ScatterAdd(_) + | LazyOp::IndexAdd(_) => true, + LazyOp::Detach(d) => { + matches!( + d.as_ref(), + LazyOp::Softmax(_) + | LazyOp::ScatterAdd(_) + | LazyOp::IndexAdd(_) + ) + } + _ => false, } - _ => false, - } - } else if !tensor.op().supports_inplace() + } else if !tensor.op().supports_inplace() // vinhowe: we need to check if the src is a variable, because we can't // inplace variables unless we've disabled gradient tracking. || to_modify_src.is_variable() - { - false - } else { - // Typical references: - // 1. Its original consumer. Whatever scope it was created in. - // 2. `tensors`, as passed into this method, if it wasn't resolved and we - // upgraded its weak reference. This happens when we do a sync of live - // tensors, say, in an optimizer step, but a one-off sync won't do this. - // This is why we have the optional `owned_tensors`. - // If these two are the only references, then we can inplace. Usually, - // additional references include, not in any particular order: - // 3. The optimizer, if it is a variable. We'll also check if the src is a - // variable. - // 4+ Any other Tensor consumers in the post-order. If it's not a variable, - // these are the references we're concerned about messing with. - // - // If we own a copy, 2, otherwise 1. - let expected_strong = owned_tensors - .as_ref() - .and_then(|ot| ot.contains(&to_modify_src.id()).then_some(2)) - .unwrap_or(1); - - to_modify_src.strong_count() == expected_strong + { + false + } else { + // Typical references: + // 1. Its original consumer. Whatever scope it was created in. + // 2. `tensors`, as passed into this method, if it wasn't resolved and we + // upgraded its weak reference. This happens when we do a sync of live + // tensors, say, in an optimizer step, but a one-off sync won't do this. + // This is why we have the optional `owned_tensors`. + // If these two are the only references, then we can inplace. Usually, + // additional references include, not in any particular order: + // 3. The optimizer, if it is a variable. We'll also check if the src is a + // variable. + // 4+ Any other Tensor consumers in the post-order. If it's not a variable, + // these are the references we're concerned about messing with. + // + // If we own a copy, 2, otherwise 1. + let expected_strong = owned_tensors + .as_ref() + .and_then(|ot| ot.contains(&to_modify_src.id()).then_some(2)) + .unwrap_or(1); + + to_modify_src.strong_count() == expected_strong + } } + None => false, + }; + + #[cfg(feature = "plotting")] + strong_counts_inplace.insert(tensor.id(), (tensor.strong_count(), can_inplace)); + log::trace!( + "Can inplace: {:?}, op: {:?} ({:?}), strong: {:?}", + can_inplace, + tensor.op().name(), + tensor.id(), + to_modify.as_ref().map(|t| t.strong_count()) + ); + let compile_key = tensor.gpu_compile_key(can_inplace, &mut uniform); + let ir = tensor.op().ir(); + ir.shape_hash(&mut hasher, &tensor_hashes, &compile_key); + if let Some(compile_key) = compile_key { + compile_keys.insert(tensor.id(), compile_key); } - None => false, - }; - - #[cfg(feature = "plotting")] - strong_counts_inplace.insert(tensor.id(), (tensor.strong_count(), can_inplace)); - log::trace!( - "Can inplace: {:?}, op: {:?} ({:?}), strong: {:?}", - can_inplace, - tensor.op().name(), - tensor.id(), - to_modify.as_ref().map(|t| t.strong_count()) - ); - let compile_key = tensor.gpu_compile_key(can_inplace, &mut uniform); - let ir = tensor.op().ir(); - ir.shape_hash(&mut hasher, &tensor_hashes, &compile_key); - if let Some(compile_key) = compile_key { - compile_keys.insert(tensor.id(), compile_key); - } - let hash = hasher.finish(); - tensor_hashes.insert(tensor.id(), hash); - log::debug!("IR: {:?}", ir); - log::debug!("Tensor hash: {:#x} (op: {:?})", hash, tensor.op().name()); - for src in tensor.op().srcs() { - consumed_tensors.insert(src.id()); + let hash = hasher.finish(); + tensor_hashes.insert(tensor.id(), hash); + log::debug!("IR: {:?}", ir); + log::debug!("Tensor hash: {:#x} (op: {:?})", hash, tensor.op().name()); + for src in tensor.op().srcs() { + used_as_src.insert(src.id()); + } + } else { + // If we've already seen this node, just add its hash to the hasher + hasher.write_u64( + *tensor_hashes + .get(&tensor.id()) + .expect("Missing shape hash for tensor"), + ); } } @@ -332,7 +361,7 @@ impl LazyGraphExecutor { let output_tensors = tensors .iter() - .filter(|(id, _)| !consumed_tensors.contains(id)) + .filter(|(id, _)| !used_as_src.contains(id)) .map(|(id, tensor)| (*id, tensor)) .collect::>(); @@ -390,19 +419,24 @@ impl LazyGraphExecutor { } } - let (mut cached_exec, do_shared_realloc) = if use_cache { + let (mut cached_exec, do_shared_realloc, is_shared_realloc) = if use_cache { self.cache .remove(&hash) .map(|cached_exec| { - if cached_exec.shared_realloc { - (Arc::try_unwrap(cached_exec.executable).ok(), false) + if cached_exec.is_shared_realloc { + // Cache hit, no need to realloc, shared realloc + (Arc::try_unwrap(cached_exec.executable).ok(), false, true) } else { - (None, true) + // Cache hit, not shared realloc and needs shared realloc, not yet shared + // realloc + (None, true, false) } }) - .unwrap_or((None, false)) + // Cache miss, no need to realloc, can't be shared realloc + .unwrap_or((None, false, false)) } else { - (None, false) + // Not using cache, no need to realloc, we don't allow shared realloc + (None, false, false) }; let mut compiled_ops = Vec::with_capacity(post_order.len()); @@ -444,6 +478,10 @@ impl LazyGraphExecutor { ) .unwrap(); + #[cfg(not(feature = "debug"))] + let mut debug_list = BTreeMap::new(); + + let mut i = 0; for t in &post_order { if t.op().is_const() || t.resolved() { continue; @@ -460,16 +498,63 @@ impl LazyGraphExecutor { } if let Some(compile_key) = compile_keys.get(&t.id()) { - if cached_exec.is_some() { - // TODO: Update debug things if needed here, otherwise, delete this branch - } else if let Some(compiled_op) = - t.compile_gpu(compile_key, gpu_device, cfg!(feature = "debug")) + let selected_for_debug = self + .step_log_config + .as_ref() + .map(|c| c.debug_selection.as_ref()) + .and_then(|s| { + s.as_ref().map(|s| match s { + DebugSelection::All => true, + DebugSelection::Some(scopes) => { + if let Some(scope) = t.scope() { + scopes.contains(&scope) + } else { + false + } + } + }) + }) + .unwrap_or(false); + + #[cfg(not(feature = "debug"))] + let debug_list_ref = &mut debug_list; + + // TODO(vinhowe): Rethink this whole thing and don't use a function here. + #[cfg(not(feature = "debug"))] + let mut set_debug_buffer = move |compiled_op: &mut Compiled| { + if selected_for_debug { + // We ignore any requests to debug copy items + if let Compiled::Compute(op) = compiled_op { + op.debug_buffer = Some(Arc::new(gpu_device.create_buffer( + &wgpu::BufferDescriptor { + label: Some("debug buffer"), + size: t.num_bytes() as _, + // If we want the values in CPU land, we'll eventually have to + // copy again to a buffer with a usage of COPY_DST | MAP_READ. + usage: wgpu::BufferUsages::standard(), + mapped_at_creation: false, + }, + ))); + debug_list_ref.insert(t.id(), (*t).clone()); + }; + }; + }; + + if let Some(exec) = cached_exec.as_mut() { + let compiled_op = &mut exec.steps[i]; + #[cfg(not(feature = "debug"))] + set_debug_buffer(compiled_op); + } else if let Some(mut compiled_op) = + t.compile_gpu(compile_key, gpu_device, selected_for_debug) { + #[cfg(not(feature = "debug"))] + set_debug_buffer(&mut compiled_op); compiled_ops.push(Some(compiled_op)); } else { log::warn!("Compilation failed for operation: {:?}", t.op().name()); compiled_ops.push(None); - } + }; + i += 1; #[cfg(feature = "debug")] compute_dsts.push((*t).clone()); @@ -498,96 +583,81 @@ impl LazyGraphExecutor { }) .collect::>(); - if use_cache { - if let Some(mut_in_debug!(cached_exec)) = cached_exec { - log::debug!("Using cached executable"); - - #[cfg(feature = "debug")] - let mut cpu_bufs = HashMap::default(); - - #[cfg(feature = "debug")] - // Get CPU buffers from existing allocations - for tensor in &post_order { - let storage_guard = tensor.storage(); - match storage_guard.as_ref() { - Some(Storage::GPU(gpu_buf)) => { - log::trace!("Getting CPU buffer for {:?}", tensor.id()); - cpu_bufs.insert( - tensor.id(), - gpu_buf.to_cpu(&Device::GPU(gpu_device.clone()))?, - ); - } - Some(Storage::CPU(cpu_buf)) => { - log::trace!("Using existing CPU buffer for {:?}", tensor.id()); - cpu_bufs.insert(tensor.id(), cpu_buf.clone()); - } - None => {} - } - } + let is_cached = cached_exec.is_some(); - #[cfg(feature = "debug")] - { - cached_exec.debug_list = Some(debug_list); - cached_exec.cpu_bufs = Some(Arc::new(RwLock::new(cpu_bufs))); - } + let mut executable; + if let Some(mut_in_debug!(cached_exec)) = cached_exec { + log::debug!("Using cached executable"); - self.run_executable(&cached_exec, gpu_device, false) - .unwrap(); + #[cfg(feature = "debug")] + let mut cpu_bufs = HashMap::default(); - #[cfg(all(feature = "debug", feature = "plotting"))] - { - let cpu_bufs_guard = cached_exec.cpu_bufs.as_ref().map(|arc| arc.read()); - - crate::plot::render_to_file( - &post_order, - &output_tensors, - &strong_counts_inplace, - cpu_bufs_guard.as_deref(), - construct_plot_filename("post_exec", self.pass_index, self.inplace_support), - ) - .unwrap(); + #[cfg(feature = "debug")] + // Get CPU buffers from existing allocations + for tensor in &post_order { + let storage_guard = tensor.storage(); + match storage_guard.as_ref() { + Some(Storage::GPU(gpu_buf)) => { + log::trace!("Getting CPU buffer for {:?}", tensor.id()); + cpu_bufs.insert( + tensor.id(), + gpu_buf.to_cpu(&Device::GPU(gpu_device.clone()))?, + ); + } + Some(Storage::CPU(cpu_buf)) => { + log::trace!("Using existing CPU buffer for {:?}", tensor.id()); + cpu_bufs.insert(tensor.id(), cpu_buf.clone()); + } + None => {} } + } - self.cache.insert( - hash, - CachedExecutable { - executable: Arc::new(cached_exec), - shared_realloc: true, - }, - ); - self.pass_index += 1; - return Ok(()); + #[cfg(feature = "debug")] + { + cached_exec.debug_list = Some(debug_list); + cached_exec.cpu_bufs = Some(Arc::new(RwLock::new(cpu_bufs))); } - // On a cache miss: Clear cache because currently I don't know how to make sure - // allocations are compatible between runs. - self.cache.clear(); - } + executable = cached_exec; + } else { + if use_cache { + // On a cache miss: Clear cache because currently I don't know how to make sure + // allocations are compatible between runs. + self.cache.clear(); + } - #[cfg(feature = "plotting")] - crate::plot::render_to_file( - &post_order, - &output_tensors, - &strong_counts_inplace, - None, - construct_plot_filename("alloc", self.pass_index, self.inplace_support), - ) - .unwrap(); + #[cfg(feature = "plotting")] + crate::plot::render_to_file( + &post_order, + &output_tensors, + &strong_counts_inplace, + None, + construct_plot_filename("alloc", self.pass_index, self.inplace_support), + ) + .unwrap(); - // Only keep the ops that successfully compiled. - let filtered_compiled_ops: Vec<_> = compiled_ops.into_iter().flatten().collect(); + // Only keep the ops that successfully compiled. + let filtered_compiled_ops: Vec<_> = compiled_ops.into_iter().flatten().collect(); - let mut executable = Executable::new( - None, - filtered_compiled_ops, - uniform.into_gpu(gpu_device)?, - #[cfg(feature = "debug")] - Some(debug_list), - #[cfg(feature = "debug")] - Some(Arc::new(RwLock::new(cpu_bufs))), - ); + executable = Executable::new( + None, + filtered_compiled_ops, + uniform.into_gpu(gpu_device)?, + #[cfg(not(feature = "debug"))] + if debug_list.is_empty() { + None + } else { + Some(debug_list) + }, + #[cfg(feature = "debug")] + Some(Arc::new(RwLock::new(cpu_bufs))), + ); + } - self.run_executable(&executable, gpu_device, false).unwrap(); + let result = self + .run_executable(&mut executable, gpu_device, false) + .await + .unwrap(); #[cfg(all(feature = "debug", feature = "plotting"))] { @@ -603,7 +673,23 @@ impl LazyGraphExecutor { .unwrap(); } - executable.set_storage(post_order.iter().map(|t| t.storage().clone()).collect()); + if !is_cached && use_cache { + // We save the storage of the executable to be used in the next pass + executable.set_storage(post_order.iter().map(|t| t.storage().clone()).collect()); + } + + if self.step_log_config.is_some() { + let step_log = StepLog::from_post_order( + post_order, + result.profiling_entries, + result.gpu_bufs, + hash, + is_cached, + is_shared_realloc, + gpu_device, + ); + gpu_device.set_last_step_log(step_log); + } if use_cache { // After creating/running the executable, we cache it @@ -611,7 +697,8 @@ impl LazyGraphExecutor { hash, CachedExecutable { executable: Arc::new(executable), - shared_realloc: do_shared_realloc, + // If we already did a shared realloc, we don't need to do it again + is_shared_realloc: is_shared_realloc || do_shared_realloc, }, ); } @@ -619,11 +706,56 @@ impl LazyGraphExecutor { self.pass_index += 1; Ok(()) } + + pub fn step_log_config(&self) -> Option<&StepLogConfig> { + self.step_log_config.as_ref() + } + + pub fn set_step_log_config(&mut self, config: StepLogConfig) { + let old_config_debug_selection = self + .step_log_config + .as_ref() + .map(|c| c.debug_selection.clone()); + // If the debug selection has changed, clear the cache; we'll need to recompile all the ops + let new_config_debug_selection = self + .step_log_config + .as_ref() + .map(|c| c.debug_selection.clone()); + if old_config_debug_selection != new_config_debug_selection { + log::debug!("Debug selection changed, clearing cache"); + self.cache.clear(); + } + self.step_log_config = Some(config); + } + + pub fn set_caching_enabled(&mut self, enabled: bool) { + self.caching_enabled = enabled; + } + + pub fn caching_enabled(&self) -> bool { + self.caching_enabled + } + + pub fn set_shared_object_allocation_enabled(&mut self, enabled: bool) { + self.shared_object_allocation_enabled = enabled; + } + + pub fn shared_object_allocation_enabled(&self) -> bool { + self.shared_object_allocation_enabled + } + + pub fn set_inplace_support(&mut self, enabled: bool) { + self.inplace_support = enabled; + } + + pub fn inplace_support(&self) -> bool { + self.inplace_support + } } impl Default for LazyGraphExecutor { fn default() -> Self { - Self::new(false) + Self::new(false, false, false) } } diff --git a/crates/ratchet-core/src/gpu/device.rs b/crates/ratchet-core/src/gpu/device.rs index c684bf08..264d28d4 100644 --- a/crates/ratchet-core/src/gpu/device.rs +++ b/crates/ratchet-core/src/gpu/device.rs @@ -1,8 +1,13 @@ use crate::{gpu::*, DType, GpuCompileKey, Tensor, TensorId}; use crate::{HashMap, TensorError}; +use maybe_async::maybe_async; use parking_lot::RwLock; use std::collections::BTreeMap; use std::{borrow::Cow, sync::Arc}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::JsCast; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::JsValue; use wgpu::{Adapter, Limits}; use crate::DeviceError; @@ -30,6 +35,7 @@ pub struct WgpuDevice { device_features: DeviceFeatures, device: Arc, queue: Arc, + last_step_log: Arc>>, } impl std::ops::Deref for WgpuDevice { @@ -65,10 +71,7 @@ impl WgpuDevice { let mut required_features = wgpu::Features::default(); required_features |= wgpu::Features::SHADER_F16; required_features |= wgpu::Features::SUBGROUP; - #[cfg(feature = "gpu-profiling")] - { - required_features |= wgpu::Features::TIMESTAMP_QUERY; - } + required_features |= wgpu::Features::TIMESTAMP_QUERY; let mut device_descriptor = wgpu::DeviceDescriptor { label: Some("Ratchet"), @@ -118,10 +121,11 @@ impl WgpuDevice { kernel_module_pool: Arc::new(KernelModulePool::new()), compute_pipeline_pool: Arc::new(ComputePipelinePool::new()), // TODO: Decide if we need some nice thing to encapsulate the lazy graph executor - lazy_graph_executor: Arc::new(RwLock::new(LazyGraphExecutor::new(true))), + lazy_graph_executor: Arc::new(RwLock::new(LazyGraphExecutor::default())), device: Arc::new(device), device_limits: limits, device_features: features, + last_step_log: Arc::new(RwLock::new(None)), }) } @@ -297,16 +301,52 @@ impl WgpuDevice { self.lazy_graph_executor.read().unregister_tensor(id); } - pub fn mark_step(&self) -> Result<(), TensorError> { + #[maybe_async] + pub async fn mark_step(&self) -> Result<(), TensorError> { self.lazy_graph_executor .write() .sync_live_tensors_graph(self) + .await } - pub fn sync_tensors_graph(&self, tensors: Vec<&Tensor>) -> Result<(), TensorError> { + #[maybe_async] + pub async fn sync_tensors_graph(&self, tensors: Vec<&Tensor>) -> Result<(), TensorError> { self.lazy_graph_executor .write() .sync_tensors_graph(tensors, self) + .await + } + + pub fn set_caching_enabled(&self, enabled: bool) { + self.lazy_graph_executor + .write() + .set_caching_enabled(enabled); + } + + pub fn caching_enabled(&self) -> bool { + self.lazy_graph_executor.read().caching_enabled() + } + + pub fn set_shared_object_allocation_enabled(&self, enabled: bool) { + self.lazy_graph_executor + .write() + .set_shared_object_allocation_enabled(enabled); + } + + pub fn shared_object_allocation_enabled(&self) -> bool { + self.lazy_graph_executor + .read() + .shared_object_allocation_enabled() + } + + pub fn set_inplace_support(&self, enabled: bool) { + self.lazy_graph_executor + .write() + .set_inplace_support(enabled); + } + + pub fn inplace_support(&self) -> bool { + self.lazy_graph_executor.read().inplace_support() } pub fn begin_pass(&self, pass_index: u64) { @@ -324,6 +364,25 @@ impl WgpuDevice { pub fn usage_bytes(&self) -> u64 { self.buffer_allocator.usage_bytes() } + + pub fn set_step_log_config(&self, config: StepLogConfig) { + self.lazy_graph_executor.write().set_step_log_config(config); + } + + pub fn take_step_log(&self) -> Option { + self.last_step_log.write().take() + } + + #[cfg(target_arch = "wasm32")] + pub fn as_webgpu_device(&self) -> Option { + JsValue::from(self.device.as_webgpu_device()) + .dyn_into::() + .ok() + } + + pub(crate) fn set_last_step_log(&self, log: StepLog) { + *self.last_step_log.write() = Some(log); + } } #[derive(Clone)] diff --git a/crates/ratchet-core/src/gpu/logging.rs b/crates/ratchet-core/src/gpu/logging.rs new file mode 100644 index 00000000..0a1a8460 --- /dev/null +++ b/crates/ratchet-core/src/gpu/logging.rs @@ -0,0 +1,231 @@ +use std::sync::Arc; + +use crate::{ + wgpu_buffer_to_cpu_buffer, DType, ExportedTensorProfilingEntry, HashMap, Shape, Tensor, + TensorId, +}; +use derive_new::new; +#[cfg(target_arch = "wasm32")] +use half::f16; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_futures::js_sys; + +use super::WgpuDevice; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DebugSelection { + All, + Some(Vec), +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] +#[derive(Default)] +pub struct StepLogConfig { + pub profiling: bool, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub debug_selection: Option, +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +impl StepLogConfig { + #[wasm_bindgen(constructor, js_name = "new")] + pub fn new_js(profiling: bool, debug_selection: JsValue) -> Self { + let mut config = Self { + profiling, + debug_selection: None, + }; + + config.set_debug_selection_js(debug_selection); + + config + } + + #[wasm_bindgen(getter, js_name = "debug_selection")] + pub fn debug_selection_js(&self) -> JsValue { + match &self.debug_selection { + Some(DebugSelection::All) => JsValue::from_str("all"), + Some(DebugSelection::Some(ids)) => { + let array = js_sys::Array::new(); + for id in ids { + array.push(&JsValue::from(id)); + } + array.into() + } + None => JsValue::from_str("none"), + } + } + + #[wasm_bindgen(setter, js_name = "debug_selection")] + pub fn set_debug_selection_js(&mut self, value: JsValue) { + self.debug_selection = if let Some(s) = value.as_string() { + if s == "all" { + Some(DebugSelection::All) + } else if s == "none" { + None + } else { + None + } + } else if js_sys::Array::is_array(&value) { + let array = js_sys::Array::from(&value); + let mut ids = Vec::new(); + + for i in 0..array.length() { + if let Some(item) = array.get(i).as_string() { + ids.push(item); + } + } + + if !ids.is_empty() { + Some(DebugSelection::Some(ids)) + } else { + None + } + } else { + None + }; + } +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] +#[derive(Debug, Clone, new)] +pub struct TensorLogStep { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub id: TensorId, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub srcs: Vec, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub gpu_buf: Option>, + pub kernel_name: String, + pub scope: Option, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub dtype: DType, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub shape: Shape, + pub profile: Option, + /// If exported, this will be a flat array of the values + pub values: Option>, + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub device: Option, +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +impl TensorLogStep { + #[wasm_bindgen(getter, js_name = "id")] + pub fn id(&self) -> usize { + self.id.0 + } + + #[wasm_bindgen(getter, js_name = "srcs")] + pub fn srcs(&self) -> Vec { + self.srcs.iter().map(|id| id.0).collect() + } + + #[wasm_bindgen(getter, js_name = "dtype")] + pub fn dtype(&self) -> String { + self.dtype.as_str().to_string() + } + + #[wasm_bindgen(getter, js_name = "shape")] + pub fn shape(&self) -> Vec { + self.shape.to_vec() + } + + #[wasm_bindgen( + unchecked_return_type = "Uint8Array|Int8Array|Uint16Array|Int16Array|Uint32Array|Int32Array|Float32Array|Float64Array|null" + )] + pub async fn cpu(&self) -> JsValue { + if let Some(gpu_buf) = self.gpu_buf.as_ref() { + let cpu_buf = wgpu_buffer_to_cpu_buffer( + gpu_buf, + self.dtype.size_of(), + None, + self.device + .as_ref() + .expect("Device should exist if GPU buffer exists"), + ) + .await; + match self.dtype { + DType::F32 => JsValue::from(js_sys::Float32Array::from( + cpu_buf.to_slice::(&self.shape), + )), + DType::F16 => JsValue::from(js_sys::Float32Array::from( + cpu_buf + .to_slice::(&self.shape) + .iter() + .map(|x| x.to_f32()) + .collect::>() + .as_slice(), + )), + DType::I32 => JsValue::from(js_sys::Int32Array::from( + cpu_buf.to_slice::(&self.shape), + )), + DType::U32 => JsValue::from(js_sys::Uint32Array::from( + cpu_buf.to_slice::(&self.shape), + )), + _ => panic!("Unsupported dtype: {:?}", self.dtype), + } + } else { + JsValue::null() + } + } + + #[wasm_bindgen(getter, unchecked_return_type = "GPUBuffer|null")] + pub fn gpu_buf(&self) -> JsValue { + self.gpu_buf + .as_ref() + .map(|buf| buf.as_webgpu_buffer().unwrap().into()) + .unwrap_or(JsValue::null()) + } +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] +#[derive(Debug, Clone, new)] +pub struct StepLog { + pub tensors: Vec, + pub cached: bool, + pub hash: u64, + pub using_shared_buffers: bool, +} + +impl StepLog { + pub fn from_post_order( + post_order: Vec<&Tensor>, + profiling_entries: Option>, + mut gpu_bufs: Option>, + hash: u64, + cached: bool, + using_shared_buffers: bool, + device: &WgpuDevice, + ) -> Self { + let tensors = post_order + .iter() + .map(|t| { + let gpu_buf = gpu_bufs + .as_mut() + .and_then(|bufs| bufs.remove(&t.id()).map(|buf| Arc::new(buf))); + TensorLogStep::new( + t.id(), + t.op().srcs().iter().map(|tensor| tensor.id()).collect(), + gpu_bufs + .as_mut() + .and_then(|bufs| bufs.remove(&t.id()).map(|buf| Arc::new(buf))), + t.op().name().to_string(), + t.scope().as_ref().map(|s| s.to_string()), + t.dt(), + t.shape().clone(), + profiling_entries + .as_ref() + .and_then(|entries| entries.get(&t.id())) + .cloned(), + None, // ...for now + gpu_buf.map(|_| device.clone()), + ) + }) + .collect(); + Self::new(tensors, cached, hash, using_shared_buffers) + } +} diff --git a/crates/ratchet-core/src/gpu/mod.rs b/crates/ratchet-core/src/gpu/mod.rs index cf38f4ed..80034cc0 100644 --- a/crates/ratchet-core/src/gpu/mod.rs +++ b/crates/ratchet-core/src/gpu/mod.rs @@ -1,25 +1,22 @@ mod align; mod buffer_allocator; mod device; +mod logging; mod pools; +mod profiler; mod uniform; mod wgsl; mod workload; -#[cfg(feature = "gpu-profiling")] -mod profiler; - pub use align::*; pub use buffer_allocator::*; pub use device::*; +pub use logging::*; pub use pools::*; +pub use profiler::*; pub use uniform::*; pub use wgsl::*; pub use workload::*; - -#[cfg(feature = "gpu-profiling")] -pub use profiler::*; - pub const MIN_STORAGE_BUFFER_SIZE: usize = 16; pub const STORAGE_BUFFER_ALIGN: usize = 256; //TODO: should be a device limit diff --git a/crates/ratchet-core/src/gpu/profiler.rs b/crates/ratchet-core/src/gpu/profiler.rs index 2c12e9f9..2f1d61a8 100644 --- a/crates/ratchet-core/src/gpu/profiler.rs +++ b/crates/ratchet-core/src/gpu/profiler.rs @@ -1,17 +1,24 @@ -#![cfg(feature = "gpu-profiling")] +use crate::{HashMap, TensorId}; +#[cfg(feature = "gpu-profiling")] use itertools::Itertools; -use std::collections::HashMap; +use maybe_async::maybe_async; +#[cfg(feature = "gpu-profiling")] use tabled::settings::{object::Rows, Alignment, Modify, Panel, Style}; +#[cfg(feature = "gpu-profiling")] use tabled::{Table, Tabled}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use wgpu::QuerySet; use super::WgpuDevice; +#[cfg(feature = "gpu-profiling")] //used for formatting table cells fn float2(n: &f64) -> String { format!("{:.2}", n) } +#[cfg(feature = "gpu-profiling")] #[derive(Tabled)] struct SummaryTableEntry { #[tabled(rename = "Op Type")] @@ -26,6 +33,7 @@ struct SummaryTableEntry { percent_runtime: f64, } +#[cfg(feature = "gpu-profiling")] pub fn build_summary_table( elapsed_map: HashMap, op_counts: HashMap, @@ -55,6 +63,7 @@ pub fn build_summary_table( .to_owned() } +#[cfg(feature = "gpu-profiling")] #[derive(Tabled)] struct IndividualTableEntry { #[tabled(rename = "Node ID")] @@ -67,6 +76,7 @@ struct IndividualTableEntry { percent_runtime: f64, } +#[cfg(feature = "gpu-profiling")] pub fn build_individual_table(elapsed_map: HashMap) -> Table { let total_elapsed: usize = elapsed_map.values().map(|(_, e)| e).sum(); @@ -92,6 +102,24 @@ pub fn build_individual_table(elapsed_map: HashMap) -> T .to_owned() } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] +#[derive(Debug, Clone)] +pub struct ExportedTensorProfilingEntry { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(skip))] + pub id: TensorId, + pub kernel_name: String, + pub elapsed: usize, +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +impl ExportedTensorProfilingEntry { + #[wasm_bindgen(getter)] + pub fn id(&self) -> TensorId { + self.id + } +} + pub struct Profiler { device: WgpuDevice, query_set: QuerySet, @@ -99,7 +127,10 @@ pub struct Profiler { destination_buffer: wgpu::Buffer, query_index: u32, timestamp_period: f32, + #[cfg(feature = "gpu-profiling")] query_to_node: HashMap<(u32, u32), (usize, String)>, + #[cfg(not(feature = "gpu-profiling"))] + query_to_tensor: HashMap<(u32, u32), (TensorId, String)>, } impl Profiler { @@ -133,14 +164,17 @@ impl Profiler { destination_buffer, query_index: 0, timestamp_period, - query_to_node: HashMap::with_capacity(count as usize), + #[cfg(feature = "gpu-profiling")] + query_to_node: HashMap::with_capacity_and_hasher(count as usize, Default::default()), + #[cfg(not(feature = "gpu-profiling"))] + query_to_tensor: HashMap::with_capacity_and_hasher(count as usize, Default::default()), } } - #[cfg(feature = "gpu-profiling")] pub fn create_timestamp_queries( &mut self, - id: usize, + #[cfg(feature = "gpu-profiling")] id: usize, + #[cfg(not(feature = "gpu-profiling"))] id: TensorId, name: &str, ) -> wgpu::ComputePassTimestampWrites { let beginning_index = self.query_index; @@ -154,13 +188,17 @@ impl Profiler { end_of_pass_write_index: Some(end_index), }; + #[cfg(feature = "gpu-profiling")] self.query_to_node .insert((beginning_index, end_index), (id, name.to_string())); + #[cfg(not(feature = "gpu-profiling"))] + self.query_to_tensor + .insert((beginning_index, end_index), (id, name.to_string())); timestamp_writes } - pub fn resolve(&self, encoder: &mut wgpu::CommandEncoder) { + pub fn resolve(&mut self, encoder: &mut wgpu::CommandEncoder) { encoder.resolve_query_set( &self.query_set, 0..self.query_index, @@ -176,6 +214,7 @@ impl Profiler { ); } + #[cfg(feature = "gpu-profiling")] fn summary_table(&self, timestamps: &[u64]) { let mut elapsed_map = HashMap::new(); let mut op_counts = HashMap::new(); @@ -198,6 +237,7 @@ impl Profiler { println!("{}", build_summary_table(elapsed_map, op_counts)); } + #[cfg(feature = "gpu-profiling")] fn node_table(&self, timestamps: &[u64]) { let mut node_map = HashMap::new(); for (idx, (begin, end)) in timestamps.iter().tuples().enumerate() { @@ -215,7 +255,8 @@ impl Profiler { println!("{}", build_individual_table(node_map)); } - pub fn read_timestamps(&self, summary: bool) { + #[cfg(feature = "gpu-profiling")] + pub fn print_timestamps(&self, summary: bool) { self.destination_buffer .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); @@ -235,4 +276,51 @@ impl Profiler { self.node_table(timestamps); } } + + #[cfg(not(feature = "gpu-profiling"))] + #[maybe_async] + pub async fn read_timestamps(&self) -> HashMap { + // I guess in principle we could do all of this in a shader... + #[cfg(target_arch = "wasm32")] + let (tx, rx) = futures_intrusive::channel::shared::oneshot_channel(); + #[cfg(not(target_arch = "wasm32"))] + let (tx, rx) = std::sync::mpsc::channel(); + self.destination_buffer + .slice(..) + .map_async(wgpu::MapMode::Read, move |_| { + tx.send(()).expect("Failed to sync for profiling"); + }); + self.device.poll(wgpu::Maintain::Wait); + #[cfg(target_arch = "wasm32")] + rx.receive().await.unwrap(); + #[cfg(not(target_arch = "wasm32"))] + rx.recv().unwrap(); + let timestamp_view = self + .destination_buffer + .slice( + ..(std::mem::size_of::() * self.query_index as usize) as wgpu::BufferAddress, + ) + .get_mapped_range(); + + let timestamps: &[u64] = bytemuck::cast_slice(×tamp_view); + let mut exported_tensors = HashMap::default(); + for (idx, chunk) in timestamps.chunks(2).enumerate() { + if let &[begin, end] = chunk { + let elapsed_ns = (end - begin) as f64 * self.timestamp_period as f64; + let (id, name) = self + .query_to_tensor + .get(&(idx as u32 * 2, idx as u32 * 2 + 1)) + .unwrap(); + exported_tensors.insert( + *id, + ExportedTensorProfilingEntry { + id: *id, + kernel_name: name.clone(), + elapsed: elapsed_ns as usize, + }, + ); + } + } + exported_tensors + } } diff --git a/crates/ratchet-core/src/lib.rs b/crates/ratchet-core/src/lib.rs index 7a8d6d48..d5b1a2ab 100644 --- a/crates/ratchet-core/src/lib.rs +++ b/crates/ratchet-core/src/lib.rs @@ -12,6 +12,7 @@ mod op; mod ops; mod plot; mod quant; +mod scope; mod shape; mod storage; mod strides; @@ -33,6 +34,7 @@ pub use op::*; pub use ops::*; pub use quant::*; use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +pub use scope::*; pub use shape::*; pub use storage::*; pub use strides::*; diff --git a/crates/ratchet-core/src/op.rs b/crates/ratchet-core/src/op.rs index d11d3e9e..2c362faf 100644 --- a/crates/ratchet-core/src/op.rs +++ b/crates/ratchet-core/src/op.rs @@ -46,6 +46,7 @@ pub enum LazyOp { // ---- Everything below this line shouldn't exist ---- FillConstant(FillConstant), FillRandn(FillRandn), + Bernoulli(Bernoulli), RoPE(RoPE), Alibi(Alibi), Softmax(Softmax), @@ -86,6 +87,7 @@ impl LazyOp { LazyOp::Trilu(t) => t.name(), LazyOp::FillConstant(f) => f.name(), LazyOp::FillRandn(f) => f.name(), + LazyOp::Bernoulli(b) => b.name(), LazyOp::Arange(a) => a.name(), LazyOp::RoPE(r) => r.name(), LazyOp::Alibi(a) => a.name(), @@ -126,6 +128,7 @@ impl LazyOp { LazyOp::Detach(d) => d.srcs(), LazyOp::View(v) => v.srcs(), LazyOp::Copy(c) => c.srcs(), + LazyOp::Bernoulli(b) => b.srcs(), LazyOp::FillConstant(_) | LazyOp::FillRandn(_) | LazyOp::Arange(_) | LazyOp::Const => { rvec![] } //end of the line kid @@ -158,6 +161,7 @@ impl LazyOp { LazyOp::Trilu(t) => t.supports_inplace(), LazyOp::FillConstant(fc) => fc.supports_inplace(), LazyOp::FillRandn(fr) => fr.supports_inplace(), + LazyOp::Bernoulli(b) => b.supports_inplace(), LazyOp::Arange(a) => a.supports_inplace(), LazyOp::Cache(c) => c.supports_inplace(), LazyOp::View(_v) => true, @@ -202,6 +206,7 @@ impl LazyOp { LazyOp::Trilu(t) => t.check_invariants(), LazyOp::FillConstant(f) => f.check_invariants(), LazyOp::FillRandn(f) => f.check_invariants(), + LazyOp::Bernoulli(b) => b.check_invariants(), LazyOp::Arange(a) => a.check_invariants(), LazyOp::Cache(c) => c.check_invariants(), LazyOp::View(v) => v.check_invariants(), @@ -237,6 +242,7 @@ impl LazyOp { LazyOp::Trilu(t) => t.ir(), LazyOp::FillConstant(f) => f.ir(), LazyOp::FillRandn(f) => f.ir(), + LazyOp::Bernoulli(b) => b.ir(), LazyOp::Arange(a) => a.ir(), LazyOp::Cache(c) => c.ir(), LazyOp::View(v) => v.ir(), @@ -760,8 +766,7 @@ pub trait GPUOperation: Operation { &self, gpu_compile_key: &ComputeCompileKey<'a>, device: &'a WgpuDevice, - #[cfg(feature = "debug")] debug: bool, - #[cfg(not(feature = "debug"))] _debug: bool, + debug: bool, ) -> Result { let ComputeCompileKey { dst, @@ -891,8 +896,9 @@ pub trait GPUOperation: Operation { storage_bind_groups, *offset as _, kernel_src_desc.key, - #[cfg(feature = "debug")] - debug_buffer, + // TODO(vinhowe): Figure out how to handle when this should be None + Some(dst.id()), + None, #[cfg(feature = "debug")] debug_input_buffers, #[cfg(feature = "debug")] diff --git a/crates/ratchet-core/src/ops/affine.rs b/crates/ratchet-core/src/ops/affine.rs index eaad1e7e..991c37c2 100644 --- a/crates/ratchet-core/src/ops/affine.rs +++ b/crates/ratchet-core/src/ops/affine.rs @@ -30,7 +30,7 @@ impl OpGuards for Affine { fn check_dtypes(&self) { let a = &self.src; - assert!(matches!(a.dt(), crate::DType::F32)); + assert!(matches!(a.dt(), crate::DType::F32 | crate::DType::F16)); } } @@ -113,13 +113,25 @@ impl KernelRenderable for AffineKernels { } }); + let mul_rep = if dst.dt() == DType::F16 { + wgsl!(f16(metadata.mul)) + } else { + wgsl!(metadata.mul) + }; + + let add_rep = if dst.dt() == DType::F16 { + wgsl!(f16(metadata.add)) + } else { + wgsl!(metadata.add) + }; + let apply = if inplace { wgsl! { let val = X[index]; - X[index] = fma(val, 'dt(metadata.mul), 'dt(metadata.add)); + X[index] = fma(val, 'dt('mul_rep), 'dt('add_rep)); } } else { - wgsl! { Y[index] = fma(X[index], 'dt(metadata.mul), 'dt(metadata.add)); } + wgsl! { Y[index] = fma(X[index], 'dt('mul_rep), 'dt('add_rep)); } }; kernel_builder.write_main(apply); Ok(kernel_builder.build()?) diff --git a/crates/ratchet-core/src/ops/bernoulli.rs b/crates/ratchet-core/src/ops/bernoulli.rs new file mode 100644 index 00000000..694201a9 --- /dev/null +++ b/crates/ratchet-core/src/ops/bernoulli.rs @@ -0,0 +1,273 @@ +use derive_new::new; +use encase::ShaderType; +use half::f16; +use inline_wgsl::wgsl; +use ratchet_macros::{IrFields, WgslMetadata}; + +use crate::{ + gpu::BindGroupLayoutDescriptor, rvec, Array, BindingMode, BuiltIn, DType, GPUOperation, Kernel, + KernelElement, KernelRenderable, KernelSource, OpGuards, Operation, OperationError, RVec, + Scalar, StorageView, Strides, Tensor, Vec2, Vec4, WgslKernelBuilder, WgslPrimitive, + WorkgroupSize, Workload, +}; + +#[derive(new, Debug, Clone, IrFields)] +pub struct Bernoulli { + pub probs: Tensor, + pub seed: Option, +} + +#[derive(Debug, derive_new::new, ShaderType, WgslMetadata)] +pub struct BernoulliMeta { + numel: u32, + seed: u32, +} + +impl Operation for Bernoulli { + fn name(&self) -> &'static str { + "Bernoulli" + } + + fn compute_view(&self) -> Result { + // Output has same shape as the input probabilities tensor + let shape = self.probs.shape().clone(); + let strides = Strides::from(&shape); + Ok(StorageView::new(shape, DType::F32, strides)) + } + + fn srcs(&self) -> RVec<&Tensor> { + rvec![&self.probs] + } + + fn supports_inplace(&self) -> bool { + false + } +} + +impl OpGuards for Bernoulli { + fn check_shapes(&self) { + // No specific shape constraints for probabilities tensor + } + + fn check_dtypes(&self) { + // Ensure probabilities tensor has floating-point dtype + assert!( + self.probs.dt().is_float(), + "Probabilities tensor must have floating-point dtype" + ); + } +} + +pub enum BernoulliKernels { + Standard(Bernoulli), +} + +impl GPUOperation for Bernoulli { + type KernelEnum = BernoulliKernels; + + fn select_kernel(&self) -> Self::KernelEnum { + BernoulliKernels::Standard(self.clone()) + } +} + +impl KernelRenderable for BernoulliKernels { + fn register_bindings( + &self, + builder: &mut WgslKernelBuilder, + _: bool, + ) -> Result<(), OperationError> { + builder.register_storage("X", BindingMode::ReadOnly, Array::

::default()); // Input probabilities + builder.register_storage("Y", BindingMode::ReadWrite, Array::

::default()); // Output binary values + builder.register_uniform(); + Ok(()) + } + + fn render( + &self, + _: bool, + dst: &Tensor, + workgroup_size: &WorkgroupSize, + ) -> Result { + let device = dst.device().try_gpu()?; + let mut kernel_builder = WgslKernelBuilder::new( + workgroup_size.clone(), + rvec![ + BuiltIn::WorkgroupId, + BuiltIn::LocalInvocationIndex, + BuiltIn::NumWorkgroups + ], + device.compute_features().clone(), + ); + + self.register_bindings::

(&mut kernel_builder, false)?; + kernel_builder.render_metadata(&self.metadata(dst, &self.kernel_element(dst))?); + + kernel_builder.write_global(wgsl! { + fn pcg_hash(input: u32) -> u32 { + let state = input * 747796405u + 2891336453u; + let word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; + return (word >> 22u) ^ word; + } + + fn rand(seed: u32) -> f32 { + return f32(pcg_hash(seed)) / 4294967295.0; + } + }); + + kernel_builder.write_main(wgsl! { + let x_offset = workgroup_id.x * 64u; + let index = (workgroup_id.y * num_workgroups.x * 64u) + x_offset + local_invocation_index; + if (index >= metadata.numel) { + return; + } + + let prob = X[index]; + let seed = index + metadata.seed; + let random_value = rand(seed); + + // If random value is less than probability, set to 1.0, otherwise 0.0 + Y[index] = f32(random_value < prob); + }); + + Ok(kernel_builder.build()?) + } +} + +impl Kernel for BernoulliKernels { + type Metadata = BernoulliMeta; + + fn kernel_name(&self) -> String { + match self { + BernoulliKernels::Standard(_) => "bernoulli".to_string(), + } + } + + fn kernel_element(&self, _dst: &Tensor) -> KernelElement { + KernelElement::Scalar + } + + fn calculate_dispatch(&self, dst: &Tensor) -> Result { + Ok(Workload::std(dst.shape().numel(), self.kernel_element(dst))) + } + + fn storage_bind_group_layout( + &self, + _inplace: bool, + ) -> Result { + Ok(BindGroupLayoutDescriptor::unary()) + } + + fn metadata(&self, dst: &Tensor, _: &KernelElement) -> Result { + let BernoulliKernels::Standard(inner) = self; + Ok(BernoulliMeta { + numel: dst.shape().numel() as u32, + seed: inner.seed.unwrap_or(0), + }) + } + + fn build_kernel( + &self, + inplace: bool, + dst: &Tensor, + workgroup_size: &WorkgroupSize, + ) -> Result { + let kernel_element = self.kernel_element(dst); + match (dst.dt(), &kernel_element) { + (DType::F32, KernelElement::Scalar) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::F32, KernelElement::Vec2) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::F32, KernelElement::Vec4) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::F16, KernelElement::Scalar) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::F16, KernelElement::Vec2) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::F16, KernelElement::Vec4) => { + self.render::>(inplace, dst, workgroup_size) + } + _ => Err(OperationError::CompileError(format!( + "Unsupported dtype {:?} or kernel element {:?}", + dst.dt(), + kernel_element + ))), + } + } +} + +#[cfg(all(test, feature = "pyo3", feature = "rand"))] +mod tests { + use test_strategy::{proptest, Arbitrary}; + + use crate::{shape, Device, DeviceRequest, Tensor}; + + fn run_bernoulli_trial(problem: BernoulliProblem, device: Device) { + let BernoulliProblem { B, M, N, seed } = problem; + + device.set_seed(seed as u64); + + // Create a tensor with random probabilities between 0 and 1 + let probs = Tensor::rand::(0f32, 1f32, shape![B, M, N], Device::CPU); + let probs_gpu = probs.to(&device).unwrap(); + + // Apply Bernoulli sampling to the probabilities tensor + let a = probs_gpu.bernoulli().unwrap(); + + // Check that all values are either 0 or 1 + let values = a.to(&Device::CPU).unwrap().to_vec::().unwrap(); + for val in values.iter() { + assert!(*val == 0.0 || *val == 1.0, "Expected binary values (0 or 1)"); + } + + // Get statistics to verify that sampling distribution is reasonable + let mean = values.iter().sum::() / values.len() as f32; + let expected_mean = probs.to(&Device::CPU).unwrap().to_vec::().unwrap().iter().sum::() / values.len() as f32; + + // Calculate observed std of the binary outcomes. + let std = (values.iter().map(|v| (v - mean).powi(2)).sum::() / values.len() as f32).sqrt(); + // For a uniformly distributed probabilities tensor, the overall variance (by total variance law) is expected to be ~0.25. + // So we square root it to get the standard deviation, 0.5. + let expected_std = 0.5; + + if (mean - expected_mean).abs() < 0.1 && (std - expected_std).abs() < 0.1 { + println!( + "\x1b[1;32mDistribution approximately bernoulli\x1b[0m - mean={} std={}", + mean, std + ); + } else { + (|| -> anyhow::Result<()> { + anyhow::bail!( + "\x1b[1;31mDistribution not bernoulli\x1b[0m - mean={} std={}", + mean, + std + ) + })() + .unwrap(); + } + } + + #[derive(Arbitrary, Debug)] + struct BernoulliProblem { + #[strategy(1..=64usize)] + B: usize, + #[strategy(1..=64usize)] + M: usize, + #[strategy(1..=64usize)] + N: usize, + #[strategy(0..=1000u32)] + seed: u32, + } + + #[proptest(cases = 8)] + fn test_bernoulli(prob: BernoulliProblem) { + let BernoulliProblem { B, M, N, seed } = prob; + println!("B = {}, M = {}, N = {}, seed = {}", B, M, N, seed); + let device = Device::request_device(DeviceRequest::GPU).unwrap(); + run_bernoulli_trial(prob, device); + } +} \ No newline at end of file diff --git a/crates/ratchet-core/src/ops/cast.rs b/crates/ratchet-core/src/ops/cast.rs index b16df323..2502a7a6 100644 --- a/crates/ratchet-core/src/ops/cast.rs +++ b/crates/ratchet-core/src/ops/cast.rs @@ -13,8 +13,8 @@ use crate::{ #[derive(new, Debug, Clone, IrFields)] pub struct Cast { - input: Tensor, - dst_dt: DType, + pub input: Tensor, + pub dst_dt: DType, } impl Cast { diff --git a/crates/ratchet-core/src/ops/cmp.rs b/crates/ratchet-core/src/ops/cmp.rs index f0369d09..e2b4c604 100644 --- a/crates/ratchet-core/src/ops/cmp.rs +++ b/crates/ratchet-core/src/ops/cmp.rs @@ -268,6 +268,15 @@ impl Kernel for CmpKernels { (DType::F16, KernelElement::Vec4) => { self.render::>(inplace, dst, workgroup_size) } + (DType::I32, KernelElement::Scalar) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::I32, KernelElement::Vec2) => { + self.render::>(inplace, dst, workgroup_size) + } + (DType::I32, KernelElement::Vec4) => { + self.render::>(inplace, dst, workgroup_size) + } _ => Err(OperationError::CompileError(format!( "Unsupported dtype {:?} or kernel element {:?}", inner.lhs.dt(), diff --git a/crates/ratchet-core/src/ops/fill_constant.rs b/crates/ratchet-core/src/ops/fill_constant.rs index 815a0a89..bada9901 100644 --- a/crates/ratchet-core/src/ops/fill_constant.rs +++ b/crates/ratchet-core/src/ops/fill_constant.rs @@ -6,10 +6,10 @@ use ratchet_macros::{IrFields, WgslMetadata}; use crate::{ gpu::{dtype::WgslDType, BindGroupLayoutDescriptor}, - rvec, Array, BindingMode, BuiltIn, DType, GPUOperation, Kernel, KernelElement, - KernelRenderable, KernelSource, OpGuards, Operation, OperationError, RVec, Scalar, Shape, - StorageView, Strides, Tensor, Vec2, Vec4, WgslKernelBuilder, WgslPrimitive, WorkgroupSize, - Workload, + rvec, Array, BindingMode, BuiltIn, DType, DynKernelMetadata, GPUOperation, Kernel, + KernelElement, KernelRenderable, KernelSource, OpGuards, Operation, OperationError, RVec, + Scalar, Shape, StorageView, Strides, Tensor, Vec2, Vec4, WgslKernelBuilder, WgslPrimitive, + WorkgroupSize, Workload, }; #[derive(new, Debug, Clone, IrFields)] @@ -18,12 +18,6 @@ pub struct FillConstant { pub value: f32, } -#[derive(Debug, derive_new::new, ShaderType, WgslMetadata)] -pub struct FillConstantMeta { - numel: u32, - value: f32, -} - impl Operation for FillConstant { fn name(&self) -> &'static str { "FillConstant" @@ -113,7 +107,7 @@ impl KernelRenderable for FillConstantKernels { } impl Kernel for FillConstantKernels { - type Metadata = FillConstantMeta; + type Metadata = DynKernelMetadata; fn kernel_name(&self) -> String { match self { @@ -145,12 +139,16 @@ impl Kernel for FillConstantKernels { Ok(BindGroupLayoutDescriptor::unary_inplace()) } - fn metadata(&self, _: &Tensor, _: &KernelElement) -> Result { - let FillConstantKernels::Standard(inner) = self; - Ok(FillConstantMeta { - numel: inner.shape.clone().numel() as u32, - value: inner.value, - }) + fn metadata(&self, dst: &Tensor, _: &KernelElement) -> Result { + let FillConstantKernels::Standard(op) = self; + let mut dyn_meta = DynKernelMetadata::new(); + dyn_meta.add_field("numel", dst.shape().numel() as u32); + if dst.dt().is_float() { + dyn_meta.add_field("value", op.value); + } else { + dyn_meta.add_field("value", op.value as i32); + } + Ok(dyn_meta) } fn build_kernel( diff --git a/crates/ratchet-core/src/ops/mod.rs b/crates/ratchet-core/src/ops/mod.rs index 833692bc..a2ae9e9c 100644 --- a/crates/ratchet-core/src/ops/mod.rs +++ b/crates/ratchet-core/src/ops/mod.rs @@ -1,6 +1,7 @@ mod affine; mod alibi; mod arange; +mod bernoulli; mod binary; mod cache; mod cast; @@ -31,6 +32,7 @@ use std::sync::Arc; pub use affine::*; pub use alibi::*; pub use arange::*; +pub use bernoulli::*; pub use binary::*; pub use cache::*; pub use cast::*; diff --git a/crates/ratchet-core/src/ops/reduce.rs b/crates/ratchet-core/src/ops/reduce.rs index fef1ac4b..cdaa93a0 100644 --- a/crates/ratchet-core/src/ops/reduce.rs +++ b/crates/ratchet-core/src/ops/reduce.rs @@ -183,7 +183,6 @@ impl OpGuards for Reduce { fn check_dtypes(&self) { let input = &self.input; assert!(self.reduce_dims.len() <= 4); - assert!(input.dt() == crate::DType::F32); } } @@ -340,6 +339,9 @@ impl Kernel for ReduceKernels { (DType::F16, KernelElement::Scalar) => { self.render::>(inplace, dst, workgroup_size) } + (DType::I32, KernelElement::Scalar) => { + self.render::>(inplace, dst, workgroup_size) + } _ => Err(OperationError::CompileError(format!( "Unsupported dtype {:?} or kernel element {:?}", inner.input.dt(), diff --git a/crates/ratchet-core/src/quant.rs b/crates/ratchet-core/src/quant.rs index 16557551..1a823a09 100644 --- a/crates/ratchet-core/src/quant.rs +++ b/crates/ratchet-core/src/quant.rs @@ -1,6 +1,7 @@ use crate::{ dtype::Quantized, gpu::STORAGE_BUFFER_ALIGN, DType, Device, Tensor, Q4_KF, Q4_KH, Q8_0F, Q8_0H, }; +use maybe_async::maybe_async; use num::integer::div_floor; use num_traits::{AsPrimitive, Float, FromPrimitive, Zero}; @@ -48,10 +49,11 @@ pub fn quantize_inner(matrix: &[Q::FP], elements: usize) -> Vec(tensor: &Tensor) -> Tensor { +#[maybe_async] +pub async fn quantize(tensor: &Tensor) -> Tensor { match (tensor.dt(), Q::dt()) { (DType::F32, DType::Q8_0F(_)) => { - let matrix = tensor.to_vec::().unwrap(); + let matrix = tensor.to_vec::().await.unwrap(); unsafe { Tensor::from_quantized( quantize_inner::(&matrix, tensor.shape().numel()), @@ -62,7 +64,7 @@ pub fn quantize(tensor: &Tensor) -> Tensor { } } (DType::F32, DType::Q4_KF(_)) => { - let matrix = tensor.to_vec::().unwrap(); + let matrix = tensor.to_vec::().await.unwrap(); unsafe { Tensor::from_quantized( quantize_inner::(&matrix, tensor.shape().numel()), @@ -73,7 +75,7 @@ pub fn quantize(tensor: &Tensor) -> Tensor { } } (DType::F16, DType::Q8_0H(_)) => { - let matrix = tensor.to_vec::().unwrap(); + let matrix = tensor.to_vec::().await.unwrap(); unsafe { Tensor::from_quantized( quantize_inner::(&matrix, tensor.shape().numel()), @@ -84,7 +86,7 @@ pub fn quantize(tensor: &Tensor) -> Tensor { } } (DType::F16, DType::Q4_KH(_)) => { - let matrix = tensor.to_vec::().unwrap(); + let matrix = tensor.to_vec::().await.unwrap(); unsafe { Tensor::from_quantized( quantize_inner::(&matrix, tensor.shape().numel()), diff --git a/crates/ratchet-core/src/scope.rs b/crates/ratchet-core/src/scope.rs new file mode 100644 index 00000000..5035bbed --- /dev/null +++ b/crates/ratchet-core/src/scope.rs @@ -0,0 +1,106 @@ +use crate::HashMap; +use std::cell::RefCell; + +// Each scope entry stores a name and the next id that was saved. +#[derive(Debug)] +struct ScopeEntry { + name: String, +} + +// The scope context holds a stack of scope entries and a counter for the next id. +#[derive(Debug)] +struct ScopeContext { + scopes: Vec, + duplicate_counter: Vec>, +} + +// Create a thread-local ScopeContext using RefCell for interior mutability. +thread_local! { + static SCOPE_CONTEXT: RefCell = RefCell::new(ScopeContext { + scopes: Vec::new(), + duplicate_counter: vec![HashMap::default()], + }); +} + +/// Returns the current scope as a concatenated string of the scope names, +/// separated by slashes. +pub fn get_current_scope() -> String { + SCOPE_CONTEXT.with(|ctx| { + let ctx = ctx.borrow(); + ctx.scopes + .iter() + .map(|entry| entry.name.clone()) + .collect::>() + .join("/") + }) +} + +/// Push a new scope with the given name. +/// This function formats the name with an id to ensure uniqueness. +fn push_scope(name: &str) { + SCOPE_CONTEXT.with(|cell| { + let mut ctx = cell.borrow_mut(); + let name_count = ctx + .duplicate_counter + .last_mut() + .unwrap() + .entry(name.to_string()) + .or_insert(0); + let formatted_name = format!("{}.{}", name, *name_count); + *name_count += 1; + // Save the current next_id (incremented by one) in the entry. + ctx.scopes.push(ScopeEntry { + name: formatted_name, + }); + ctx.duplicate_counter.push(HashMap::default()); + }); +} + +/// Pop the most recent scope off the stack. +/// Panics if there are no scopes to pop. +fn pop_scope() { + SCOPE_CONTEXT.with(|ctx| { + let mut ctx = ctx.borrow_mut(); + if !ctx.scopes.is_empty() { + ctx.duplicate_counter.pop(); + ctx.scopes.pop(); + } else { + panic!("Attempted to pop scope from an empty stack"); + } + }); +} + +/// Resets the scope context, ensuring that there are no remaining scopes. +/// Panics if the scope stack is not empty. +pub fn reset_scope_context() { + SCOPE_CONTEXT.with(|ctx| { + let mut ctx = ctx.borrow_mut(); + if !ctx.scopes.is_empty() || ctx.duplicate_counter.len() > 1 { + panic!( + "Expecting scope to be empty but it is '{}'", + get_current_scope() + ); + } + ctx.duplicate_counter.last_mut().unwrap().clear(); + }); +} + +/// A RAII-style scope pusher that pushes a scope on creation and pops it +/// when dropped. +pub struct ScopePusher; + +impl ScopePusher { + /// Create a new scope pusher that pushes the given scope. + pub fn new(name: &str) -> Self { + push_scope(name); + ScopePusher + } +} + +// When a ScopePusher goes out of scope, its Drop implementation will automatically +// pop the scope. +impl Drop for ScopePusher { + fn drop(&mut self) { + pop_scope(); + } +} diff --git a/crates/ratchet-core/src/shape.rs b/crates/ratchet-core/src/shape.rs index ca0c6641..4b387c75 100644 --- a/crates/ratchet-core/src/shape.rs +++ b/crates/ratchet-core/src/shape.rs @@ -4,8 +4,11 @@ use std::{ ops::{RangeFrom, RangeTo}, slice::Iter, }; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg_attr(target_arch = "wasm32", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, PartialEq, Eq, Hash, Default)] pub struct Shape(RVec); diff --git a/crates/ratchet-core/src/tensor.rs b/crates/ratchet-core/src/tensor.rs index 655f98db..656aa851 100644 --- a/crates/ratchet-core/src/tensor.rs +++ b/crates/ratchet-core/src/tensor.rs @@ -1,8 +1,9 @@ use crate::gpu::{BindGroupEntry, CpuUniform, WgpuDevice}; use crate::{ - cpu, ops::*, rvec, shape, BufferSegment, CPUBuffer, Compiled, CompiledOp, ComputeCompileKey, - DType, Device, DeviceStorage, GPUOperation, GpuCompileKey, InvariantError, LazyOp, Operation, - OperationError, RVec, RawCPUBuffer, Shape, Storage, Strides, TensorDType, TensorId, + cpu, get_current_scope, ops::*, rvec, shape, BufferSegment, CPUBuffer, Compiled, CompiledOp, + ComputeCompileKey, DType, Device, DeviceStorage, GPUOperation, GpuCompileKey, InvariantError, + LazyOp, Operation, OperationError, RVec, RawCPUBuffer, ScopePusher, Shape, Storage, Strides, + TensorDType, TensorId, }; use bitvec::prelude::*; use derive_new::new; @@ -55,8 +56,9 @@ pub struct Tensor { unsafe impl Send for Tensor {} -macro_rules! ensure_resolved { +macro_rules! ensure_resolved_sync { ($self:ident) => { + #[cfg(not(target_arch = "wasm32"))] if !$self.resolved() { $self .apply_pending_graph() @@ -65,6 +67,26 @@ macro_rules! ensure_resolved { }; } +macro_rules! ensure_resolved { + ($self:ident) => { + if !$self.resolved() { + #[cfg(target_arch = "wasm32")] + { + $self + .apply_pending_graph() + .await + .expect("Failed to apply pending graph"); + } + #[cfg(not(target_arch = "wasm32"))] + { + $self + .apply_pending_graph() + .expect("Failed to apply pending graph"); + } + } + }; +} + impl Tensor { fn register_with_device(&self) { if let Device::GPU(inner) = self.device() { @@ -80,8 +102,16 @@ impl Tensor { device: Device, is_variable: bool, ) -> Self { + let _scope_guard = ScopePusher::new(op.name()); let value = Self { - inner: Arc::new(Inner::new(op, meta, storage, device.clone(), is_variable)), + inner: Arc::new(Inner::new( + op, + Some(get_current_scope()), + meta, + storage, + device.clone(), + is_variable, + )), }; value.register_with_device(); value @@ -135,8 +165,16 @@ impl Tensor { device: Device, is_variable: bool, ) -> Self { + let _scope_guard = ScopePusher::new(op.name()); let value = Self { - inner: Arc::new(Inner::from_shallow(op, meta, storage, device, is_variable)), + inner: Arc::new(Inner::from_shallow( + op, + Some(get_current_scope()), + meta, + storage, + device, + is_variable, + )), }; value.register_with_device(); value @@ -227,6 +265,7 @@ impl Drop for Inner { #[derive(Debug)] pub struct Inner { id: TensorId, + scope: Option, op: LazyOp, device: Device, view: StorageView, @@ -243,6 +282,7 @@ impl AsRef for Inner { impl Inner { fn new( op: LazyOp, + scope: Option, meta: StorageView, storage: Option, device: Device, @@ -250,6 +290,7 @@ impl Inner { ) -> Self { Self { id: TensorId::new(), + scope, view: meta, op, device, @@ -260,6 +301,7 @@ impl Inner { fn from_shallow( op: LazyOp, + scope: Option, meta: StorageView, storage: Arc>>, device: Device, @@ -267,6 +309,7 @@ impl Inner { ) -> Self { Self { id: TensorId::new(), + scope, view: meta, op, device, @@ -322,6 +365,10 @@ impl Tensor { &self.inner.op } + pub fn scope(&self) -> &Option { + &self.inner.scope + } + pub fn is_scalar(&self) -> bool { self.shape().is_scalar() } @@ -1222,6 +1269,28 @@ impl Tensor { Self::rand_impl::(lo, up, shape, device, false) } + #[cfg(feature = "rand")] + pub fn bernoulli(self) -> anyhow::Result { + let rng = self.device().get_rng(); + let seed = rng.write().next_u32(); + let shape = self.shape(); + let device = self.device().clone(); + + let meta = StorageView { + shape: shape.clone(), + dt: DType::F32, + strides: Strides::from(shape), + }; + + Ok(Self::new_impl( + LazyOp::Bernoulli(Bernoulli::new(self, Some(seed))), + meta, + None, + device, + false, + )) + } + pub(crate) fn zeros_impl>( shape: &Shape, device: &Device, @@ -1477,7 +1546,8 @@ impl Tensor { )) } - pub fn item(&self) -> T { + #[maybe_async] + pub async fn item(&self) -> T { assert!(self.is_scalar()); ensure_resolved!(self); let storage_guard = self.storage(); @@ -1524,7 +1594,8 @@ impl Tensor { /// Converts the tensor into a 1D vector. /// /// The 1D vector contains the data from the tensor, as it was laid out in memory. - pub fn to_vec(&self) -> anyhow::Result> { + #[maybe_async] + pub async fn to_vec(&self) -> anyhow::Result> { ensure_resolved!(self); let storage_guard = self.storage(); let buffer = storage_guard.as_ref().unwrap().try_cpu()?; @@ -1579,8 +1650,9 @@ impl Tensor { order } - pub fn cpu_apply(self, dst: Tensor) -> Option { - cpu::apply_operation(self.op().clone(), dst).ok() + #[maybe_async] + pub async fn cpu_apply(self, dst: Tensor) -> Option { + cpu::apply_operation(self.op().clone(), dst).await.ok() } fn gpu_compile_key_for_op<'a>( @@ -1616,6 +1688,7 @@ impl Tensor { LazyOp::Gather(g) => g.create_gpu_compile_key(self, can_inplace, uniform).ok(), LazyOp::FillConstant(f) => f.create_gpu_compile_key(self, can_inplace, uniform).ok(), LazyOp::FillRandn(f) => f.create_gpu_compile_key(self, can_inplace, uniform).ok(), + LazyOp::Bernoulli(b) => b.create_gpu_compile_key(self, can_inplace, uniform).ok(), LazyOp::Arange(a) => a.create_gpu_compile_key(self, can_inplace, uniform).ok(), LazyOp::Copy(_) | LazyOp::View(_) | LazyOp::Const => None, } @@ -1654,7 +1727,8 @@ impl Tensor { } } - fn resolve_cpu(self) -> Result { + #[maybe_async] + async fn resolve_cpu(self) -> Result { let mut tensor = self.clone(); let execution_order = self.execution_order(); @@ -1664,28 +1738,47 @@ impl Tensor { if t.resolved() { continue; } - tensor = tensor.cpu_apply(t.clone()).unwrap(); + tensor = tensor.cpu_apply(t.clone()).await.unwrap(); } Ok(tensor.clone()) } /// Applies the pending graph to the tensor. - fn apply_pending_graph(&self) -> Result { + #[maybe_async] + async fn apply_pending_graph(&self) -> Result { if self.resolved() { return Ok(self.clone()); } match self.device() { Device::GPU(gpu_device) => { - gpu_device.sync_tensors_graph(vec![&self])?; + #[cfg(target_arch = "wasm32")] + { + Box::pin(gpu_device.sync_tensors_graph(vec![&self])).await?; + } + #[cfg(not(target_arch = "wasm32"))] + { + gpu_device.sync_tensors_graph(vec![&self])?; + } + Ok(self.clone()) + } + Device::CPU => { + #[cfg(target_arch = "wasm32")] + { + Box::pin(self.clone().resolve_cpu()).await?; + } + #[cfg(not(target_arch = "wasm32"))] + { + self.clone().resolve_cpu()?; + } Ok(self.clone()) } - Device::CPU => self.clone().resolve_cpu(), } } - fn to_gpu(&self, dst_device: &Device) -> Result { + #[maybe_async] + async fn to_gpu(&self, dst_device: &Device) -> Result { ensure_resolved!(self); let storage_guard = self.storage(); let cpu_buf = storage_guard @@ -1704,7 +1797,8 @@ impl Tensor { )) } - pub fn deep_clone(&self) -> Tensor { + #[maybe_async] + pub async fn deep_clone(&self) -> Tensor { ensure_resolved!(self); let storage_guard = self.storage(); let storage = storage_guard.as_ref().unwrap(); @@ -1750,7 +1844,7 @@ impl Tensor { pub async fn to(&self, device: &Device) -> Result { match (self.device(), device) { (Device::GPU(_), Device::CPU) => self.to_cpu().await, - (Device::CPU, Device::GPU(_)) => self.to_gpu(device), + (Device::CPU, Device::GPU(_)) => self.to_gpu(device).await, _ => Ok(self.clone()), } } @@ -1802,6 +1896,7 @@ pub fn compile_gpu_for_op( LazyOp::Gather(g) => g.compile_gpu(gpu_compile_key, gpu_device, debug).ok(), LazyOp::FillConstant(f) => f.compile_gpu(gpu_compile_key, gpu_device, debug).ok(), LazyOp::FillRandn(f) => f.compile_gpu(gpu_compile_key, gpu_device, debug).ok(), + LazyOp::Bernoulli(b) => b.compile_gpu(gpu_compile_key, gpu_device, debug).ok(), LazyOp::Arange(a) => a.compile_gpu(gpu_compile_key, gpu_device, debug).ok(), LazyOp::View(_) | LazyOp::Const => None, LazyOp::Copy(_) => panic!("Copy should not have a gpu_compile_key"), @@ -1927,7 +2022,7 @@ impl Tensor { } pub fn to_ndarray_view(&self) -> ArrayViewD { - ensure_resolved!(self); + ensure_resolved_sync!(self); assert!(self.device().is_cpu()); assert!(self.dt() == T::dt()); let shape = self.shape().to_vec(); diff --git a/crates/ratchet-core/src/tensor_id.rs b/crates/ratchet-core/src/tensor_id.rs index e3691705..61a415cf 100644 --- a/crates/ratchet-core/src/tensor_id.rs +++ b/crates/ratchet-core/src/tensor_id.rs @@ -1,6 +1,10 @@ +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + /// Unique identifier for tensors. #[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct TensorId(pub(crate) usize); +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +pub struct TensorId(pub usize); impl std::fmt::Debug for TensorId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/crates/ratchet-core/src/test_utils.rs b/crates/ratchet-core/src/test_utils.rs index 436b8cce..503c22d2 100644 --- a/crates/ratchet-core/src/test_utils.rs +++ b/crates/ratchet-core/src/test_utils.rs @@ -4,14 +4,14 @@ use maybe_async::maybe_async; #[maybe_async] pub async fn to_vec0_round(t: &Tensor, digits: i32) -> anyhow::Result { let b = 10f32.powi(digits); - let t = t.to(&Device::CPU).await?.to_vec::()?[0]; + let t = t.to(&Device::CPU).await?.to_vec::().await?[0]; Ok(f32::round(t * b) / b) } #[maybe_async] pub async fn to_vec1_round(t: &Tensor, digits: i32) -> anyhow::Result> { let b = 10f32.powi(digits); - let t = t.to(&Device::CPU).await?.to_vec::()?; + let t = t.to(&Device::CPU).await?.to_vec::().await?; let t = t.iter().map(|t| f32::round(t * b) / b).collect(); Ok(t) } diff --git a/crates/ratchet-core/tests/caching.rs b/crates/ratchet-core/tests/caching.rs new file mode 100644 index 00000000..c31decc4 --- /dev/null +++ b/crates/ratchet-core/tests/caching.rs @@ -0,0 +1,43 @@ +// TODO(vinhowe): Remove or motivate this test +#[test] +fn test_simple_caching() -> anyhow::Result<()> { + let _ = env_logger::builder().is_test(true).try_init(); + + let device = Device::request_device(DeviceRequest::GPU).unwrap(); + let t1 = Tensor::from_data(vec![1f32], shape![1], Device::CPU) + .to(&device)? + .square()?; + println!("t1: {:?}", t1.to(&Device::CPU)?.to_vec::()?); + + assert_eq!(t1.to(&Device::CPU)?.to_vec::()?, vec![1f32]); + + let t2 = Tensor::from_data(vec![2f32], shape![1], Device::CPU) + .to(&device)? + .square()?; + println!("t2: {:?}", t2.to(&Device::CPU)?.to_vec::()?); + + assert_eq!(t2.to(&Device::CPU)?.to_vec::()?, vec![4f32]); + + let t3 = Tensor::from_data(vec![3f32], shape![1], Device::CPU) + .to(&device)? + .square()?; + println!("t3: {:?}", t3.to(&Device::CPU)?.to_vec::()?); + + assert_eq!(t3.to(&Device::CPU)?.to_vec::()?, vec![9f32]); + + let t4 = Tensor::from_data(vec![4f32], shape![1], Device::CPU) + .to(&device)? + .square()?; + println!("t4: {:?}", t4.to(&Device::CPU)?.to_vec::()?); + + assert_eq!(t4.to(&Device::CPU)?.to_vec::()?, vec![16f32]); + + let t5 = Tensor::from_data(vec![5f32], shape![1], Device::CPU) + .to(&device)? + .square()?; + println!("t5: {:?}", t5.to(&Device::CPU)?.to_vec::()?); + + assert_eq!(t5.to(&Device::CPU)?.to_vec::()?, vec![25f32]); + + Ok(()) +} diff --git a/crates/ratchet-loader/Cargo.toml b/crates/ratchet-loader/Cargo.toml index 24d46bb5..759e5a8a 100644 --- a/crates/ratchet-loader/Cargo.toml +++ b/crates/ratchet-loader/Cargo.toml @@ -17,7 +17,7 @@ itertools = { workspace = true } env_logger.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen = "0.2.84" +wasm-bindgen = { workspace = true } serde = { workspace = true, features = ["derive"] } [dev-dependencies] diff --git a/crates/ratchet-macros/src/lib.rs b/crates/ratchet-macros/src/lib.rs index 09fc8c80..d37c6064 100644 --- a/crates/ratchet-macros/src/lib.rs +++ b/crates/ratchet-macros/src/lib.rs @@ -1,4 +1,5 @@ mod ir_fields; +mod scoped_module; mod wgsl_metadata; use proc_macro::TokenStream; @@ -21,3 +22,11 @@ pub fn derive_ir_fields(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input); ir_fields::derive(input).into() } + +/// Derives the `ScopedModule` trait implementation for a struct. +/// +/// Automatically adds scoping to Module implementations +#[proc_macro_attribute] +pub fn scoped_module(_attr: TokenStream, item: TokenStream) -> TokenStream { + scoped_module::scoped_module(item).into() +} diff --git a/crates/ratchet-macros/src/scoped_module.rs b/crates/ratchet-macros/src/scoped_module.rs new file mode 100644 index 00000000..0e6e8843 --- /dev/null +++ b/crates/ratchet-macros/src/scoped_module.rs @@ -0,0 +1,64 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, ImplItem, ItemImpl, Type}; + +pub fn scoped_module(item: TokenStream) -> TokenStream { + let mut impl_block = parse_macro_input!(item as ItemImpl); + let self_ty = &impl_block.self_ty; + + let mut has_module_name = false; + + for item in &impl_block.items { + if let ImplItem::Fn(method) = item { + if method.sig.ident == "module_name" { + has_module_name = true; + break; + } + } + } + + for item in &mut impl_block.items { + if let ImplItem::Fn(method) = item { + if method.sig.ident == "schedule" { + let original_body = method.block.clone(); + + method.block = syn::parse2(quote! { + { + let _scope_guard = ratchet::ScopePusher::new(&format!("mod:{}", self.module_name())); + + #original_body + } + }) + .unwrap(); + + break; + } + } + } + + // Generate a default module_name if not present + if !has_module_name { + let type_name = match self_ty.as_ref() { + Type::Path(type_path) => { + if let Some(segment) = type_path.path.segments.last() { + segment.ident.to_string() + } else { + "unknown".to_string() + } + } + _ => "unknown".to_string(), + }; + + let module_name_method = quote! { + fn module_name(&self) -> &str { + #type_name + } + }; + + impl_block + .items + .push(syn::parse2(module_name_method).unwrap()); + } + + quote! { #impl_block }.into() +} diff --git a/crates/ratchet-models/Cargo.toml b/crates/ratchet-models/Cargo.toml index 7a672dbe..735a62a3 100644 --- a/crates/ratchet-models/Cargo.toml +++ b/crates/ratchet-models/Cargo.toml @@ -27,6 +27,7 @@ ratchet = { path = "../ratchet-core" } ratchet-nn = { path = "../ratchet-nn" } ratchet-loader = { path = "../ratchet-loader" } ratchet-datasets = { path = "../ratchet-datasets" } +ratchet-macros = { path = "../ratchet-macros" } byteorder.workspace = true anyhow.workspace = true thiserror.workspace = true diff --git a/crates/ratchet-models/src/gpt2/attn.rs b/crates/ratchet-models/src/gpt2/attn.rs index f92481ca..1a34757c 100644 --- a/crates/ratchet-models/src/gpt2/attn.rs +++ b/crates/ratchet-models/src/gpt2/attn.rs @@ -2,8 +2,10 @@ use std::{cell::RefCell, rc::Rc}; use maybe_async::maybe_async; use ratchet::{prelude::shape, rvec, Tensor}; +use ratchet_macros::scoped_module; use ratchet_nn::{ - AlibiEmbedding, AlibiInput, KVCache, Linear, Module, RotaryEmbedding, RotaryInput, VarBuilder, + AlibiEmbedding, AlibiInput, Dropout, KVCache, Linear, Module, RotaryEmbedding, RotaryInput, + VarBuilder, }; use super::{ @@ -22,6 +24,8 @@ pub struct GPT2SelfAttention { h_dim: usize, rope: Option, alibi: Option, + attn_dropout: Option, + resid_dropout: Option, } impl GPT2SelfAttention { @@ -46,7 +50,20 @@ impl GPT2SelfAttention { None, Some(AlibiEmbedding::new(cfg.n_head, 8.0)), // max_bias=8.0 is a common default ), - PositionalEncoding::Learned | PositionalEncoding::Sinusoidal => (None, None), + PositionalEncoding::Learned + | PositionalEncoding::Sinusoidal + | PositionalEncoding::None => (None, None), + }; + + let attn_dropout = if cfg.attn_pdrop > 0.0 { + Some(Dropout::new(cfg.attn_pdrop)) + } else { + None + }; + let resid_dropout = if cfg.resid_pdrop > 0.0 { + Some(Dropout::new(cfg.resid_pdrop)) + } else { + None }; Ok(Self { @@ -58,6 +75,8 @@ impl GPT2SelfAttention { h_dim, rope, alibi, + attn_dropout, + resid_dropout, }) } } @@ -69,6 +88,7 @@ pub struct GPT2AttnInput { pub cache: Rc>, } +#[scoped_module] impl Module for GPT2SelfAttention { type Input = GPT2AttnInput; type Output = (Tensor, Tensor); @@ -104,19 +124,32 @@ impl Module for GPT2SelfAttention { let mut q = q.view(qkv_shape.clone())?.permute(&[0, 2, 1, 3])?; let v = v.view(qkv_shape.clone())?.permute(&[0, 2, 1, 3])?; + let cache_entry = if cache.borrow_mut().use_kv_cache() { + let cache_ref = cache.borrow_mut(); + let entry = cache_ref[block_idx].clone(); + Some(entry) + } else { + None + }; + let offset = cache_entry.as_ref().map(|kv| kv.entries).unwrap_or(0); // Apply RoPE if enabled if let Some(rope) = &self.rope { - q = rope.schedule(RotaryInput { - input: q, - offset: index_pos, - })?; - k = rope.schedule(RotaryInput { - input: k, - offset: index_pos, - })?; + q = rope.schedule(RotaryInput { input: q, offset })?; + k = rope.schedule(RotaryInput { input: k, offset })?; } - let mut att = q.matmul(k, false, true)?.mul(self.softmax_scale.clone())?; + let (k, v) = if let Some(cache_entry) = cache_entry { + let k_cache = cache_entry.k_cache.cache(k, 2, offset)?; + let v_cache = cache_entry.v_cache.cache(v, 2, offset)?; + (k_cache, v_cache) + } else { + (k, v) + }; + + let mut att = q + .clone() + .matmul(k.clone(), false, true)? + .mul(self.softmax_scale.clone())?; // Apply ALiBi if enabled if let Some(alibi) = &self.alibi { @@ -134,13 +167,21 @@ impl Module for GPT2SelfAttention { }; let att = att.softmax(3)?; + let att = match &self.attn_dropout { + Some(dropout) => dropout.schedule(att)?, + None => att, + }; let y = att .clone() - .matmul(v, false, false)? + .matmul(v.clone(), false, false)? .permute(&[0, 2, 1, 3])? .view(shape![batch_size as _, q_len, self.n_embd])?; let y = self.c_proj.schedule(y)?; + let y = match &self.resid_dropout { + Some(dropout) => dropout.schedule(y)?, + None => y, + }; Ok((y, att)) } diff --git a/crates/ratchet-models/src/gpt2/generate.rs b/crates/ratchet-models/src/gpt2/generate.rs index 984c242b..cbf8d9f0 100644 --- a/crates/ratchet-models/src/gpt2/generate.rs +++ b/crates/ratchet-models/src/gpt2/generate.rs @@ -1,57 +1,118 @@ -#![cfg(target_arch = "wasm32")] -use crate::gpt2::GPT2; -use crate::TokenOutputStream; -use ndarray::Axis; +use crate::gpt2::{GPT2Input, GPT2}; +use maybe_async::maybe_async; +use ndarray::{Array3, Axis, Ix3}; use ndarray_stats::QuantileExt; use ratchet::{shape, Device, Tensor}; -use ratchet_nn::Module; -use tokenizers::Tokenizer; +use ratchet_nn::{Module, ModuleMode, ModuleModeGuard}; +#[maybe_async] pub async fn generate( model: &mut GPT2, - tokenizer: Tokenizer, - prompt: String, - callback: impl Fn(String), -) -> anyhow::Result<()> { - use web_time::Instant; - log::warn!("Prompt: {}", prompt); - - let mut tos = TokenOutputStream::new(tokenizer); - let encoding = tos.tokenizer().encode(prompt, true).unwrap(); - let mut tokens = encoding - .get_ids() - .iter() - .map(|&x| x as i32) - .collect::>(); - let mut all_tokens = tokens.clone(); - let mut loop_cnt = 0; - let start = Instant::now(); - while tokens[tokens.len() - 1] != 50256 && loop_cnt < 256 { + prompt: Vec, + // The callback now receives: + // - A Vec of the tokens fed in this pass (either the prompt, or the latest token) + // - An ndarray (shape: [1, seq_len, vocab_size]) containing the logits for that pass. + // - An ndarray (shape: [1, seq_len, seq_len]) containing the attention probabilities for that pass. + callback: impl Fn(Vec, Array3, Vec), + max_tokens: usize, +) -> anyhow::Result>> { + let _eval_mode_guard = ModuleModeGuard::new(ModuleMode::Eval); + + // Preserve original cache setting and enable kv-cache for generation. + let use_kv_cache = model.cache_mut().use_kv_cache(); + model.cache_mut().set_use_kv_cache(true); + + // This vector will accumulate the logits (as ndarray on CPU) from each model call. + let mut all_logits_ndarray: Vec> = Vec::new(); + + // all_tokens holds the entire context (prompt + generated tokens). + let mut all_tokens = prompt.clone(); + // Count only the tokens that are generated (not in the original prompt) + let mut generated_count = 0; + + while generated_count < max_tokens && all_tokens[all_tokens.len() - 1] != 256 { + // For the first pass, feed the entire prompt. + // For subsequent passes, feed only the latest generated token. + let tokens_to_feed = if generated_count == 0 { + &all_tokens[..] + } else { + &all_tokens[all_tokens.len() - 1..] + }; + + // Build the input tensor from tokens_to_feed. let input = Tensor::from_data( - tokens.clone(), - shape![1, tokens.len()], + tokens_to_feed, + shape![1, tokens_to_feed.len()], model.device.clone(), ); - let result = model.schedule(input)?; - let logits = result.to(&Device::CPU).await?; - model.cache_mut().update(tokens.len()); - tokens = logits + // The index_pos is the total length of the context so far. + let (result, attn_probs) = model.schedule(GPT2Input { + x: input, + index_pos: all_tokens.len(), + })?; + + // Bring the logits to the CPU. + let logits_cpu = result.to(&Device::CPU).await?; + + // Update the kv-cache: + // - For the first pass, update with the full length. + // - For subsequent passes, update only with the new token. + if generated_count == 0 { + model.cache_mut().update(all_tokens.len() + 1); + } else { + model.cache_mut().update(1); + } + + // Convert the logits to an owned ndarray. + // The logits have shape [1, seq_len, vocab_size] where: + // - seq_len == prompt.len() on first pass, or 1 on subsequent passes. + let logits_nd = logits_cpu .to_ndarray_view::() - .map_axis(Axis(2), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); + .into_owned() + .into_dimensionality::() + .unwrap(); + // Store them in our accumulator. + all_logits_ndarray.push(logits_nd.clone()); + + let attn_probs_cpu = attn_probs + .to(&Device::CPU) + .await + .map_err(|e| e.to_string()) + .unwrap(); + let attn_probs_shape = attn_probs_cpu.shape().to_vec(); + let attn_probs_data = attn_probs_cpu + .to_vec::() + .await + .map_err(|e| e.to_string()) + .unwrap(); + + // *** Stream the current pass via the callback *** + // Pass the tokens that were fed (as a Vec) and the corresponding logits ndarray. + callback(tokens_to_feed.to_vec(), logits_nd.clone(), attn_probs_data); - if let Some(t) = tos.next_token(tokens[0] as u32)? { - callback(t); + // Extract the logits for the last token in this pass: + // - For the first pass, that's at index (prompt.len() - 1). + // - For later passes, the only token is at index 0. + let seq_len_this_pass = tokens_to_feed.len(); + let last_logits = logits_nd.index_axis(Axis(1), seq_len_this_pass - 1); + // last_logits has shape [1, vocab_size]; take the 0th row. + let vocab_logits = last_logits.index_axis(Axis(0), 0); + // Use argmax_skipnan from ndarray_stats to get the next token id. + let next_token_id = vocab_logits.argmax_skipnan().unwrap() as i32; + + // Stop if the end-of-text token is generated. + if next_token_id == 50256 { + break; } - all_tokens.extend(tokens.clone()); - loop_cnt += 1; + + // Append the generated token to the full context. + all_tokens.push(next_token_id); + generated_count += 1; } - let elapsed = start.elapsed(); - log::warn!("Elapsed: {:?}", elapsed); - log::warn!("Tok/s {}", all_tokens.len() as f64 / elapsed.as_secs_f64()); + + // Clean up: reset model state and restore the original kv-cache setting. model.reset(); - Ok(()) + model.cache_mut().set_use_kv_cache(use_kv_cache); + Ok(all_logits_ndarray) } diff --git a/crates/ratchet-models/src/gpt2/mlp.rs b/crates/ratchet-models/src/gpt2/mlp.rs index 422e0b49..3b70e6fe 100644 --- a/crates/ratchet-models/src/gpt2/mlp.rs +++ b/crates/ratchet-models/src/gpt2/mlp.rs @@ -1,5 +1,6 @@ use maybe_async::maybe_async; use ratchet::Tensor; +use ratchet_macros::scoped_module; use ratchet_nn::{Linear, Module, VarBuilder}; use super::{ @@ -26,6 +27,7 @@ impl MLP { } } +#[scoped_module] impl Module for MLP { type Input = Tensor; type Output = Tensor; diff --git a/crates/ratchet-models/src/gpt2/mod.rs b/crates/ratchet-models/src/gpt2/mod.rs index da60582c..2a4edae6 100644 --- a/crates/ratchet-models/src/gpt2/mod.rs +++ b/crates/ratchet-models/src/gpt2/mod.rs @@ -1,5 +1,5 @@ mod attn; -// mod generate; +mod generate; mod linear; mod mlp; mod model; @@ -10,5 +10,4 @@ pub use model::LayerNormPosition; pub use model::PositionalEncoding; pub use model::GPT2; -// #[cfg(target_arch = "wasm32")] -// pub use generate::generate; +pub use generate::generate; diff --git a/crates/ratchet-models/src/gpt2/model.rs b/crates/ratchet-models/src/gpt2/model.rs index e3f12af7..a5f4cd0c 100644 --- a/crates/ratchet-models/src/gpt2/model.rs +++ b/crates/ratchet-models/src/gpt2/model.rs @@ -1,4 +1,25 @@ -/// This is not a true GPT2 model, in that we probably couldn't load the weights from a GGML file. +/// GPT2 model, state-dict-compatible with minGPT, except for "bias" buffer, which is easy enough +/// to add back in: +/// +/// ```python +/// from safetensors.torch import load_file +/// n_layer = 6 +/// state_dict = load_file("our-gpt2.safetensors") +/// bias_buffer = torch.tril(torch.ones(24, 24)).view(1, 1, 24, 24) +/// state_dict["lm_head.bias"] = bias_buffer +/// for i in range(n_layer): +/// state_dict[f"transformer.h.{i}.attn.bias"] = bias_buffer +/// ``` +/// +/// You can then load the state_dict into minGPT with: +/// +/// ```python +/// from mingpt.model import GPT +/// config = GPT.get_default_config() +/// # ... set config appropriately ... +/// model = GPT(config) +/// model.load_state_dict(state_dict) +/// ``` use std::{cell::RefCell, rc::Rc}; use super::{ @@ -8,9 +29,10 @@ use super::{ }; use maybe_async::maybe_async; use ratchet::{shape, Device, Tensor}; +use ratchet_macros::scoped_module; use ratchet_nn::{ - embedding, layer_norm, Embedding, KVCache, LayerNorm, Linear, Module, SinusoidalEmbedding, - SinusoidalInput, VarBuilder, + embedding, layer_norm, Dropout, Embedding, KVCache, LayerNorm, Linear, Module, + SinusoidalEmbedding, SinusoidalInput, VarBuilder, }; #[derive(Debug, Clone, PartialEq)] @@ -19,12 +41,14 @@ pub enum PositionalEncoding { RoPE, ALiBi, Sinusoidal, + None, } #[derive(Debug, Clone, PartialEq)] pub enum LayerNormPosition { Pre, Post, + None, } // https://huggingface.co/microsoft/Phi-3-mini-4k-instruct/blob/main/config.json @@ -39,6 +63,9 @@ pub struct Config { pub attention_only: bool, pub positional_encoding: PositionalEncoding, pub layernorm_position: LayerNormPosition, + pub embd_pdrop: f32, + pub attn_pdrop: f32, + pub resid_pdrop: f32, } impl Config { @@ -49,37 +76,38 @@ impl Config { #[derive(Debug)] pub struct DecoderLayer { - input_norm: LayerNorm, - self_attn: GPT2SelfAttention, - ffn_norm: LayerNorm, + ln_1: LayerNorm, + attn: GPT2SelfAttention, + ln_2: LayerNorm, mlp: MLP, attention_only: bool, layernorm_position: LayerNormPosition, + dropout: Option, } impl DecoderLayer { #[maybe_async] async fn new(cfg: &Config, vb: VarBuilder<'_>) -> anyhow::Result { - let self_attn = GPT2SelfAttention::new(cfg, vb.pp("self_attn")).await?; + let attn = GPT2SelfAttention::new(cfg, vb.pp("attn")).await?; - let input_norm = - layer_norm(cfg.n_embd, Default::default(), vb.pp("input_layernorm")).await?; - let ffn_norm = layer_norm( - cfg.n_embd, - Default::default(), - vb.pp("post_attention_layernorm"), - ) - .await?; + let ln_1 = layer_norm(cfg.n_embd, Default::default(), vb.pp("ln_1")).await?; + let ln_2 = layer_norm(cfg.n_embd, Default::default(), vb.pp("ln_2")).await?; let mlp = MLP::new(cfg, vb.pp("mlp")).await?; + let dropout = if cfg.resid_pdrop > 0.0 { + Some(Dropout::new(cfg.resid_pdrop)) + } else { + None + }; Ok(Self { - self_attn, + attn, mlp, - input_norm, - ffn_norm, + ln_1, + ln_2, attention_only: cfg.attention_only, layernorm_position: cfg.layernorm_position.clone(), + dropout, }) } } @@ -92,6 +120,7 @@ pub struct DecoderLayerInput { pub cache: Rc>, } +#[scoped_module] impl Module for DecoderLayer { type Input = DecoderLayerInput; type Output = (Tensor, Tensor); @@ -105,46 +134,42 @@ impl Module for DecoderLayer { } = input; let residual = x.clone(); - let (attn_output, attn_masks) = match self.layernorm_position { - LayerNormPosition::Pre => { - let xs = self.input_norm.schedule(x)?; - let (attn_output, attn_masks) = self.self_attn.schedule(GPT2AttnInput { - input: xs, - index_pos, - block_idx, - cache, - })?; - (residual.add(attn_output)?, attn_masks) - } - LayerNormPosition::Post => { - let (attn_output, attn_masks) = self.self_attn.schedule(GPT2AttnInput { - input: x, - index_pos, - block_idx, - cache, - })?; - let xs = self.input_norm.schedule(residual.add(attn_output)?)?; - (xs, attn_masks) - } + let x = match self.layernorm_position { + LayerNormPosition::Pre => self.ln_1.schedule(x)?, + LayerNormPosition::Post | LayerNormPosition::None => x, + }; + let (attn_output, attn_masks) = self.attn.schedule(GPT2AttnInput { + input: x, + index_pos, + block_idx, + cache, + })?; + let x = residual.add(attn_output)?; + let x = match self.layernorm_position { + LayerNormPosition::Post => self.ln_1.schedule(x)?, + LayerNormPosition::Pre | LayerNormPosition::None => x, }; // Skip the feed-forward network if attention_only is true if !self.attention_only { - let residual = attn_output.clone(); - let xs = match self.layernorm_position { - LayerNormPosition::Pre => { - let xs = self.ffn_norm.schedule(attn_output)?; - let xs = self.mlp.schedule(xs)?; - residual.add(xs)? - } - LayerNormPosition::Post => { - let xs = self.mlp.schedule(self.ffn_norm.schedule(attn_output)?)?; - self.ffn_norm.schedule(residual.add(xs)?)? - } + let residual = x.clone(); + let x = match self.layernorm_position { + LayerNormPosition::Pre => self.ln_2.schedule(x)?, + LayerNormPosition::Post | LayerNormPosition::None => x, + }; + let x = self.mlp.schedule(x)?; + let x = match &self.dropout { + Some(dropout) => dropout.schedule(x)?, + None => x, }; - Ok((xs, attn_masks)) + let x = residual.add(x)?; + let x = match self.layernorm_position { + LayerNormPosition::Post => self.ln_2.schedule(x)?, + LayerNormPosition::Pre | LayerNormPosition::None => x, + }; + Ok((x, attn_masks)) } else { - Ok((attn_output, attn_masks)) + Ok((x, attn_masks)) } } } @@ -155,8 +180,9 @@ pub struct GPT2 { pub wpe: Option, pub sinusoidal: Option, pub layers: Vec, - pub ln_post: LayerNorm, + pub ln_f: LayerNorm, pub lm_head: Linear, + pub embd_dropout: Option, pub kv_cache: Rc>, pub device: Device, } @@ -166,6 +192,7 @@ pub struct GPT2Input { pub index_pos: usize, } +#[scoped_module] impl Module for GPT2 { type Input = GPT2Input; type Output = (Tensor, Tensor); @@ -192,6 +219,11 @@ impl Module for GPT2 { } // For RoPE and ALiBi, positional encoding is handled in the attention layer + let mut x = match &self.embd_dropout { + Some(dropout) => dropout.schedule(x)?, + None => x, + }; + let mut attn_masks = vec![]; for (block_idx, layer) in self.layers.iter().enumerate() { @@ -207,7 +239,7 @@ impl Module for GPT2 { } let attn_masks = Tensor::stack(attn_masks.into(), 0)?; - x = self.ln_post.schedule(x)?; + x = self.ln_f.schedule(x)?; let logits = self.lm_head.schedule(x)?; Ok((logits, attn_masks)) } @@ -217,8 +249,8 @@ impl Module for GPT2 { impl GPT2 { const MAX_CACHE: usize = 4096; - pub async fn new(cfg: &Config, vb: VarBuilder<'_>) -> anyhow::Result { - let vb_m = vb.pp("model"); + pub async fn new(cfg: &Config, vb: VarBuilder<'_>, use_kv_cache: bool) -> anyhow::Result { + let vb_m = vb.pp("transformer"); let wte = embedding(cfg.vocab_size, cfg.n_embd, vb_m.pp("wte")).await?; // Initialize positional encoding based on the type @@ -232,43 +264,58 @@ impl GPT2 { Some(SinusoidalEmbedding::new(cfg.n_embd, vb.device())?), ), PositionalEncoding::RoPE | PositionalEncoding::ALiBi => (None, None), + PositionalEncoding::None => (None, None), }; let n_layers = cfg.n_layer as _; let mut layers = Vec::with_capacity(n_layers); - let vb_l = vb_m.pp("layers"); + let vb_l = vb_m.pp("h"); for layer_idx in 0..n_layers { let layer = DecoderLayer::new(cfg, vb_l.pp(layer_idx)).await?; layers.push(layer) } - let ln_post = layer_norm(cfg.n_embd, Default::default(), vb_m.pp("norm")).await?; + let ln_f = layer_norm(cfg.n_embd, Default::default(), vb_m.pp("ln_f")).await?; let lm_head = linear_no_bias_gpt2(cfg.n_embd, cfg.vocab_size, vb.pp("lm_head")).await?; + let embd_dropout = if cfg.embd_pdrop > 0.0 { + Some(Dropout::new(cfg.embd_pdrop)) + } else { + None + }; - let cache_shape = shape![1, n_layers as _, Self::MAX_CACHE, cfg.head_dim() as _]; + let cache_shape = shape![1, cfg.n_head as _, Self::MAX_CACHE, cfg.head_dim() as _]; Ok(Self { wte, wpe, sinusoidal, layers, - ln_post, + ln_f, lm_head, + embd_dropout, kv_cache: Rc::new(RefCell::new(KVCache::new::( n_layers as _, - false, + use_kv_cache, cache_shape, vb.device(), ))), device: vb.device().clone(), }) } + + pub fn reset(&mut self) { + self.kv_cache.borrow_mut().reset(); + } + + pub fn cache_mut(&mut self) -> std::cell::RefMut<'_, KVCache> { + (*self.kv_cache).borrow_mut() + } } #[cfg(all(test, not(target_arch = "wasm32"), feature = "pyo3"))] mod tests { - use ratchet::{prelude::shape, DType, Device, DeviceRequest, Tensor, Var}; + use ratchet::{prelude::shape, DType, Device, DeviceRequest, StepLogConfig, Tensor, Var}; use ratchet_datasets::{ nlp::{ tinystories::{Dataset, DatasetRandomIter}, @@ -282,7 +329,11 @@ mod tests { }; use super::GPT2; - use crate::gpt2::model::{Config, GPT2Input, PositionalEncoding}; + use crate::gpt2::{ + generate, + model::{Config, GPT2Input, PositionalEncoding}, + LayerNormPosition, + }; #[test] #[cfg_attr(feature = "ci", ignore)] @@ -303,12 +354,15 @@ mod tests { attention_only: false, positional_encoding: PositionalEncoding::Learned, layernorm_position: LayerNormPosition::Pre, + embd_pdrop: 0.1, + attn_pdrop: 0.1, + resid_pdrop: 0.1, }; let varmap = VarMap::new(); let vb = VarBuilder::from_varmap(&varmap, ratchet::DType::F32, &device.clone()); - let model = GPT2::new(&config, vb)?; + let model = GPT2::new(&config, vb, false)?; let params = ParamsAdamW { lr: 1e-4, @@ -372,12 +426,15 @@ mod tests { attention_only: false, positional_encoding: PositionalEncoding::Learned, layernorm_position: LayerNormPosition::Pre, + embd_pdrop: 0.1, + attn_pdrop: 0.1, + resid_pdrop: 0.1, }; let varmap = VarMap::new(); let vb = VarBuilder::from_varmap(&varmap, ratchet::DType::F32, &device.clone()); - let model = GPT2::new(&config, vb)?; + let model = GPT2::new(&config, vb, false)?; const BATCH_SIZE: usize = 10; @@ -420,16 +477,28 @@ mod tests { n_head: 4, block_size: SEQUENCE_LENGTH, attention_only: false, - positional_encoding: PositionalEncoding::Sinusoidal, + positional_encoding: PositionalEncoding::Learned, layernorm_position: LayerNormPosition::Pre, + embd_pdrop: 0.1, + attn_pdrop: 0.1, + resid_pdrop: 0.1, }; let device = Device::request_device(ratchet::DeviceRequest::GPU).unwrap(); + // If you want to enable profiling: + // device + // .try_gpu() + // .unwrap() + // .set_step_log_config(StepLogConfig { + // profiling: true, + // ..Default::default() + // }); + let varmap = VarMap::new(); let vb = VarBuilder::from_varmap(&varmap, DType::F32, &device.clone()); - let model = GPT2::new(&config, vb).unwrap(); + let mut model = GPT2::new(&config, vb, false).unwrap(); let params = ParamsAdamW { lr: 1e-4, @@ -454,7 +523,7 @@ mod tests { let batch_iter = Batcher::new_r2(dataset_iter).batch_size(BATCH_SIZE); for (batch_index, batch) in batch_iter.enumerate() { - if batch_index > 10 { + if batch_index > 100 { break; } @@ -475,6 +544,21 @@ mod tests { println!("{:?} loss: {:?}, norm: {:?}", batch_index, loss_vec[0], "?"); } + + model.reset(); + + // Uncomment this to generate a sequence from the model: + // generate( + // &mut model, + // "12,35,07,99,03:134=".chars().map(|c| c as i32).collect(), + // |s, _logits| { + // println!("{}", s.iter().map(|&c| c as u8 as char).collect::()); + // // println!("{:?}", logits); + // }, + // 24, + // ) + // .unwrap(); + Ok(()) } @@ -512,12 +596,15 @@ mod tests { attention_only: false, positional_encoding: PositionalEncoding::Learned, layernorm_position: LayerNormPosition::Pre, + embd_pdrop: 0.1, + attn_pdrop: 0.1, + resid_pdrop: 0.1, }; let iter = DatasetRandomIter::new(&dataset, false, config.block_size, device.clone()); let batch_iter = Batcher::new_r2(iter).batch_size(BATCH_SIZE); - let model = GPT2::new(&config, vb)?; + let model = GPT2::new(&config, vb, false)?; let params = ParamsAdamW { lr: 0.0001, @@ -556,4 +643,45 @@ mod tests { Ok(()) } + + #[test] + fn generate_from_initialization() -> anyhow::Result<()> { + let _ = env_logger::builder().is_test(true).try_init(); + + let device = Device::request_device(DeviceRequest::GPU).unwrap(); + + let varmap = VarMap::new(); + let vb = VarBuilder::from_varmap(&varmap, ratchet::DType::F32, &device.clone()); + + let config = Config { + vocab_size: 256, + hidden_act: ratchet_nn::Activation::Relu2, + n_embd: 128, + n_layer: 1, + n_head: 1, + block_size: 20, + attention_only: false, + positional_encoding: PositionalEncoding::Learned, + layernorm_position: LayerNormPosition::Pre, + embd_pdrop: 0.1, + attn_pdrop: 0.1, + resid_pdrop: 0.1, + }; + + let mut model = GPT2::new(&config, vb, false)?; + + // Uncomment this to generate a uninitialized sequence from the model: + // generate( + // &mut model, + // "Hello, world".chars().map(|c| c as i32).collect(), + // |s, logits| { + // println!("{:?}", s); + // println!("{:?}", logits); + // }, + // 24, + // ) + // .unwrap(); + + Ok(()) + } } diff --git a/crates/ratchet-models/src/lib.rs b/crates/ratchet-models/src/lib.rs index 7cb943d3..f9ed2527 100644 --- a/crates/ratchet-models/src/lib.rs +++ b/crates/ratchet-models/src/lib.rs @@ -1,11 +1,9 @@ #![allow(clippy::upper_case_acronyms)] pub mod gpt2; -// pub mod moondream; // pub mod phi2; // pub mod phi3; pub mod registry; mod token_stream; -// pub mod whisper; pub use token_stream::TokenOutputStream; #[cfg(target_arch = "wasm32")] diff --git a/crates/ratchet-models/src/moondream/generate.rs b/crates/ratchet-models/src/moondream/generate.rs deleted file mode 100644 index 2a97b599..00000000 --- a/crates/ratchet-models/src/moondream/generate.rs +++ /dev/null @@ -1,207 +0,0 @@ -use super::model::Moondream; -use crate::TokenOutputStream; -use ndarray::Axis; -use ndarray_stats::QuantileExt; -use ratchet::shape; -use ratchet::Device; -use ratchet::Tensor; -use ratchet_nn::Module; -use tokenizers::Tokenizer; - -#[cfg(not(target_arch = "wasm32"))] -pub fn generate( - model: &mut Moondream, - image_bytes: &[u8], - question: String, - tokenizer: Tokenizer, - callback: impl Fn(String), -) -> anyhow::Result<()> { - use ratchet::rvec; - use web_time::Instant; - let device = model.text_model.device.clone(); - - let prompt = format!("\n\nQuestion: {}\n\nAnswer:", question); - log::warn!("Prompt: {}", prompt); - - let mut tos = TokenOutputStream::new(tokenizer); - - let img = image::ImageReader::new(std::io::Cursor::new(image_bytes)) - .with_guessed_format()? - .decode() - .unwrap() - .resize_to_fill(378, 378, image::imageops::FilterType::Triangle); // Adjusted to 378x378 - - let pixels: Vec<_> = img - .to_rgb8() - .to_vec() - .iter() - .map(|&x| (x as f32 / 255.0)) - .collect(); - - let img_tensor = Tensor::from_data(pixels, shape![378, 378, 3], device.clone()) - .permute(&[2, 0, 1])? - .view(shape![1, 3, 378, 378])? - .cast(device.compute_precision())?; - - let img_embed = model.vision_encoder.schedule(img_tensor)?.resolve()?; - - let bos_token = model - .text_model - .embedding - .schedule(Tensor::from_data([50256], shape![1], device.clone()))? - .view(shape![1, 1, 2048])?; - - let encoding = tos.tokenizer().encode(prompt, false).unwrap(); - - let mut tokens = encoding - .get_ids() - .iter() - .map(|&x| x as i32) - .collect::>(); - - let mut all_tokens = tokens.clone(); - - let start = Instant::now(); - let mut generated_tokens = vec![]; - while *tokens.last().unwrap() != 50256 { - let input = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let mut embeds: Tensor; - if generated_tokens.is_empty() { - embeds = model.text_model.embedding.schedule(input)?; - embeds = Tensor::cat( - rvec![bos_token.clone(), img_embed.clone(), embeds.clone()], - 1, - )?; - } else { - embeds = model.text_model.embedding.schedule(input).unwrap(); - } - - let result = model - .text_model - .schedule(embeds.clone())? - .full()? - .resolve()?; - - model.text_model.cache_mut().update(embeds.shape()[1]); - - let logits = result.to(&Device::CPU).unwrap(); - let next_tokens = logits - .to_ndarray_view::() - .map_axis(Axis(2), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - tokens = next_tokens.clone(); - generated_tokens.extend(next_tokens.clone()); - all_tokens.extend(next_tokens.clone()); - - if let Some(t) = tos.next_token(next_tokens[0] as u32)? { - callback(t); - } - } - - let elapsed = start.elapsed(); - log::warn!("Elapsed: {:?}", elapsed); - log::warn!("Tok/s {}", all_tokens.len() as f64 / elapsed.as_secs_f64()); - model.text_model.reset(); - Ok(()) -} - -#[cfg(target_arch = "wasm32")] -pub async fn generate( - model: &mut Moondream, - image_bytes: Vec, - question: String, - tokenizer: Tokenizer, - callback: impl Fn(String), -) -> anyhow::Result<()> { - use web_time::Instant; - let device = model.text_model.device.clone(); - - let img = image::io::Reader::new(std::io::Cursor::new(image_bytes)) - .with_guessed_format()? - .decode() - .unwrap() - .resize_to_fill(378, 378, image::imageops::FilterType::Triangle); // Adjusted to 378x378 - - let prompt = format!("\n\nQuestion: {}\n\nAnswer:", question); - log::warn!("Prompt: {}", prompt); - - let mut tos = TokenOutputStream::new(tokenizer); - - let pixels: Vec<_> = img - .to_rgb8() - .to_vec() - .iter() - .map(|&x| (x as f32 / 255.0)) - .collect(); - - let img_tensor = Tensor::from_data(&pixels, shape![378, 378, 3], device.clone()) - .permute(&[2, 0, 1])? - .view(shape![1, 3, 378, 378])?; - - let img_embed = model.vision_encoder.schedule(img_tensor)?.resolve()?; - - let bos_token = model - .text_model - .embedding - .schedule(Tensor::from_data([50256], shape![1], device.clone()))? - .view(shape![1, 1, 2048])?; - - let encoding = tos.tokenizer().encode(prompt, false).unwrap(); - - let mut tokens = encoding - .get_ids() - .iter() - .map(|&x| x as i32) - .collect::>(); - - let mut all_tokens = tokens.clone(); - - let start = Instant::now(); - let mut generated_tokens = vec![]; - while *tokens.last().unwrap() != 50256 { - let input = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let mut embeds: Tensor; - if generated_tokens.len() == 0 { - embeds = model.text_model.embedding.schedule(input).unwrap(); - embeds = Tensor::cat( - vec![bos_token.clone(), img_embed.clone(), embeds.clone()].into(), - 1, - ) - .unwrap(); - } else { - embeds = model.text_model.embedding.schedule(input).unwrap(); - } - - let result = model - .text_model - .schedule(embeds.clone())? - .full()? - .resolve()?; - - model.text_model.cache_mut().update(embeds.shape()[1]); - - let logits = result.to(&Device::CPU).await.unwrap(); - let next_tokens = logits - .to_ndarray_view::() - .map_axis(Axis(2), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - tokens = next_tokens.clone(); - generated_tokens.extend(next_tokens.clone()); - all_tokens.extend(next_tokens.clone()); - - if let Some(t) = tos.next_token(next_tokens[0] as u32)? { - callback(t); - } - } - - let elapsed = start.elapsed(); - log::warn!("Elapsed: {:?}", elapsed); - log::warn!("Tok/s {}", all_tokens.len() as f64 / elapsed.as_secs_f64()); - println!("Tok/s {}", all_tokens.len() as f64 / elapsed.as_secs_f64()); - model.text_model.reset(); - Ok(()) -} diff --git a/crates/ratchet-models/src/moondream/mlp.rs b/crates/ratchet-models/src/moondream/mlp.rs deleted file mode 100644 index e94c02ec..00000000 --- a/crates/ratchet-models/src/moondream/mlp.rs +++ /dev/null @@ -1,18 +0,0 @@ -use ratchet::Tensor; -use ratchet_nn::{Linear, Module}; - -#[derive(Debug, derive_new::new)] -pub struct MLP { - pub fc1: Linear, - pub fc2: Linear, -} - -impl Module for MLP { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let input_dt = input.dt(); - self.fc2 - .schedule(self.fc1.schedule(input)?.full()?.gelu()?.cast(input_dt)?) - } -} diff --git a/crates/ratchet-models/src/moondream/mod.rs b/crates/ratchet-models/src/moondream/mod.rs deleted file mode 100644 index 02d58c48..00000000 --- a/crates/ratchet-models/src/moondream/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod generate; -mod mlp; -pub mod model; -mod text_model; -mod vision_encoder; - -pub use generate::generate; -pub use model::Moondream; diff --git a/crates/ratchet-models/src/moondream/model.rs b/crates/ratchet-models/src/moondream/model.rs deleted file mode 100644 index 37ccfa26..00000000 --- a/crates/ratchet-models/src/moondream/model.rs +++ /dev/null @@ -1,284 +0,0 @@ -use std::io::{BufRead, Seek}; - -use anyhow::Ok; -use half::f16; -use ratchet::{shape, DType, Device, Tensor}; -use ratchet_loader::gguf::gguf::Header; -use ratchet_nn::{Embedding, KVCache, LayerNorm, Linear, RotaryEmbedding}; - -#[cfg(target_arch = "wasm32")] -use {crate::ratchet_from_gguf_web, crate::TensorMap}; - -use super::{ - mlp::MLP, - text_model::{DecoderLayer, SelfAttention, TextModel}, - vision_encoder::{ - Attention, LinearPatchEmbedding, VisionEncoder, VisionProjection, VisionTransformer, - VitBlock, - }, -}; - -#[derive(Debug)] -pub struct Moondream { - pub vision_encoder: VisionEncoder, - pub text_model: TextModel, -} - -impl Moondream { - pub fn load( - header: Header, - reader: &mut R, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| header.tensor(reader, name, device).unwrap(); - Self::load_inner(&header, lt, device) - } - - #[cfg(target_arch = "wasm32")] - pub async fn from_web(header: Header, mut tensors: TensorMap) -> anyhow::Result { - let device = Device::request_device(ratchet::DeviceRequest::GPU).await?; - let mut lt = |name: &str| { - let tensor = tensors - .remove(name) - .ok_or_else(|| anyhow::anyhow!("missing tensor")); - ratchet_from_gguf_web(tensor.unwrap(), &device).unwrap() - }; - Self::load_inner(&header, lt, &device) - } - - fn load_inner(_header: &Header, mut lt: F, device: &Device) -> anyhow::Result - where - F: FnMut(&str) -> Tensor, - { - let n_layers = 24_i32; - let dim = 2048_f32; - let n_heads = 32_u32; - let n_kv_heads = 32_u32; - let rope_base = 10000.0f32; - let rope_dim = 32_u32; - let ln_eps = 1e-05; - let hdim = dim / n_heads as f32; - let softmax_scale = Tensor::from_data([1.0 / hdim.sqrt()], shape![1], device.clone()); - let cache_shape = shape![1, 32, 4096, 64]; - - let kv_cache = match device.compute_precision() { - DType::F16 => KVCache::new::(n_layers as _, cache_shape, device), - DType::F32 => KVCache::new::(n_layers as _, cache_shape, device), - _ => unimplemented!(), - }; - - let text_model = TextModel::new( - Embedding::new(lt("text_model.transformer.embd.wte.weight")), - (0..n_layers) - .map(|i| { - DecoderLayer::new( - LayerNorm::new( - lt(&format!("text_model.transformer.h.{}.ln.weight", i)), - Some(lt(&format!("text_model.transformer.h.{}.ln.bias", i))), - ln_eps, - ), - SelfAttention::new( - Linear::new( - lt(&format!("text_model.transformer.h.{}.mixer.Wqkv.weight", i)), - Some(lt(&format!( - "text_model.transformer.h.{}.mixer.Wqkv.bias", - i - ))), - ), - Linear::new( - lt(&format!( - "text_model.transformer.h.{}.mixer.out_proj.weight", - i - )), - Some(lt(&format!( - "text_model.transformer.h.{}.mixer.out_proj.bias", - i - ))), - ), - RotaryEmbedding::new(rope_dim as usize, false, rope_base, 1.0), - n_heads, - softmax_scale.clone(), - n_kv_heads, - ), - MLP::new( - Linear::new( - lt(&format!("text_model.transformer.h.{}.mlp.fc1.weight", i)), - Some(lt(&format!("text_model.transformer.h.{}.mlp.fc1.bias", i))), - ), - Linear::new( - lt(&format!("text_model.transformer.h.{}.mlp.fc2.weight", i)), - Some(lt(&format!("text_model.transformer.h.{}.mlp.fc2.bias", i))), - ), - ), - ) - }) - .collect(), - LayerNorm::new( - lt("text_model.lm_head.ln.weight"), - Some(lt("text_model.lm_head.ln.bias")), - ln_eps, - ), - Linear::new( - lt("text_model.lm_head.linear.weight"), - Some(lt("text_model.lm_head.linear.bias")), - ), - kv_cache, - device.clone(), - ); - - let projection = VisionProjection::new(MLP::new( - Linear::new( - lt("vision_encoder.projection.mlp.fc1.weight"), - Some(lt("vision_encoder.projection.mlp.fc1.bias")), - ), - Linear::new( - lt("vision_encoder.projection.mlp.fc2.weight"), - Some(lt("vision_encoder.projection.mlp.fc2.bias")), - ), - )); - - let transformer = VisionTransformer::new( - LinearPatchEmbedding::new( - Linear::new(lt("vision_encoder.encoder.model.visual.patch_embed.linear.weight"), Some(lt("vision_encoder.encoder.model.visual.patch_embed.linear.bias"))), - ), - lt("vision_encoder.encoder.model.visual.pos_embed"), - (0..27) - .map(|layer| { - let qkvw = lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.attn.qkv.weight", layer)); - let qkvb = lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.attn.qkv.bias", layer)); - - let n_heads = 16; - let dim = 1152; - let h_dim = dim / n_heads; - let scale_factor = - Tensor::from_data([1.0 / (h_dim as f32).sqrt()], shape![1], device.clone()); - - VitBlock::new( - 1152, - Attention::new( - n_heads, - dim, - Linear::new(qkvw, Some(qkvb)), - Linear::new( - lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.attn.proj.weight", layer)), - Some(lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.attn.proj.bias", layer))), - ), - scale_factor, - ), - MLP::new( - Linear::new( - lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.mlp.fc1.weight", layer)), - Some(lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.mlp.fc1.bias", layer))), - ), - Linear::new( - lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.mlp.fc2.weight", layer)), - Some(lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.mlp.fc2.bias", layer))), - ), - ), - LayerNorm::new( - lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.norm1.weight", layer)), - Some(lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.norm1.bias", layer))), - ln_eps, - ), - LayerNorm::new( - lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.norm2.weight", layer)), - Some(lt(&format!("vision_encoder.encoder.model.visual.blocks.{}.norm2.bias", layer))), - ln_eps, - ), - ) - }).collect::>(), - LayerNorm::new(lt("vision_encoder.encoder.model.visual.norm.weight"), Some(lt("vision_encoder.encoder.model.visual.norm.bias")), ln_eps), - ); - - let vision_encoder = VisionEncoder::new(projection, transformer); - Ok(Self { - vision_encoder, - text_model, - }) - } -} - -#[cfg(all(test, not(target_arch = "wasm32"), feature = "pyo3"))] -mod tests { - use std::fs; - - use anyhow::Ok; - use hf_hub::api::sync::Api; - use ratchet::{shape, test_util::run_py_prg, Device, DeviceRequest, Tensor}; - use ratchet_loader::gguf; - use ratchet_nn::Module; - use tokenizers::Tokenizer; - - use crate::moondream::{ - generate::generate, text_model::TextModel, vision_encoder::VisionEncoder, - }; - - use super::Moondream; - - fn vision_ground_truth(tensor: Tensor) -> anyhow::Result { - let prg = r#" -from transformers import AutoModelForCausalLM, AutoTokenizer -import torch - -def ground(*args): - tensor = torch.from_numpy(args[0]) - model_id = "vikhyatk/moondream2" - revision = "2024-05-20" - model = AutoModelForCausalLM.from_pretrained( - model_id, trust_remote_code=True, revision=revision - ) - return model.encode_image(tensor).numpy() -"#; - - run_py_prg(prg.to_string(), &[&tensor], &[], ratchet::DType::F32) - } - - #[test] - #[cfg_attr(feature = "ci", ignore)] - fn moondream_encoder() -> anyhow::Result<()> { - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - let api = Api::new().unwrap(); - let model_repo = api.model("ratchet-community/ratchet-moondream-2".to_string()); - let model_path = model_repo.get("moondream_f32.gguf").unwrap(); - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path).unwrap()); - let content = gguf::gguf::Header::read(&mut reader).unwrap(); - let model = Moondream::load(content, &mut reader, &device).unwrap(); - - let input = Tensor::randn::(shape![1, 3, 378, 378], device); - let ours = model - .vision_encoder - .schedule(input.clone())? - .resolve()? - .to(&Device::CPU)?; - let theirs = vision_ground_truth(input.to(&Device::CPU).unwrap()).unwrap(); - ours.all_close(&theirs, 1e-1, 1e-1).unwrap(); - Ok(()) - } - - #[test] - #[cfg_attr(feature = "ci", ignore)] - fn moondream_end_to_end() { - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - let api = Api::new().unwrap(); - let model_repo = api.model("ratchet-community/ratchet-moondream-2".to_string()); - let model_path = model_repo.get("moondream_q8_0.gguf").unwrap(); - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path).unwrap()); - let content = gguf::gguf::Header::read(&mut reader).unwrap(); - let mut model = Moondream::load(content, &mut reader, &device).unwrap(); - - let tokenizer_path = model_repo.get("tokenizer.json").unwrap(); - let tokenizer = Tokenizer::from_file(tokenizer_path).unwrap(); - - let img_path = model_repo.get("demo.jpg").unwrap(); - let img = fs::read(img_path).unwrap(); - - generate( - &mut model, - &img, - "What is happening here?".to_owned(), - tokenizer, - |token| print!("{}", token), - ) - .unwrap(); - } -} diff --git a/crates/ratchet-models/src/moondream/text_model.rs b/crates/ratchet-models/src/moondream/text_model.rs deleted file mode 100644 index 57bb4a91..00000000 --- a/crates/ratchet-models/src/moondream/text_model.rs +++ /dev/null @@ -1,192 +0,0 @@ -use ratchet::{rvec, shape, Device, Tensor}; -use ratchet_nn::{ - Embedding, KVCache, KVEntry, LayerNorm, Linear, Module, RotaryEmbedding, RotaryInput, -}; - -use super::mlp::MLP; - -#[derive(Debug, derive_new::new)] -pub struct SelfAttention { - qkv: Linear, - o: Linear, - rope: RotaryEmbedding, - n_heads: u32, - softmax_scale: Tensor, - n_kv_heads: u32, -} - -pub struct AttnInput { - pub input: Tensor, - pub mask: Option, - pub kv_cache: Option, -} - -impl Module for SelfAttention { - type Input = AttnInput; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let AttnInput { - input, - mask, - kv_cache, - } = input; - let [batch_size, q_len, n_state]: [usize; 3] = input.shape().try_into()?; - - let hdim = n_state / self.n_heads as usize; - let kv_x_hdim = self.n_kv_heads as usize * hdim; - - let qkv = self.qkv.schedule(input)?; - let query_pos = self.n_heads as usize * hdim; - let key_pos = query_pos + kv_x_hdim; - let value_pos = key_pos + kv_x_hdim; - - let query_states = qkv - .clone() - .slice(&[0..batch_size, 0..q_len, 0..query_pos])?; - let key_states = qkv - .clone() - .slice(&[0..batch_size, 0..q_len, query_pos..key_pos])?; - let value_states = qkv - .clone() - .slice(&[0..batch_size, 0..q_len, key_pos..value_pos])?; - - let q_shape = shape![batch_size as _, q_len, self.n_heads as _, hdim]; - let kv_shape = shape![batch_size as _, q_len, self.n_kv_heads as _, hdim]; - - let query_states = query_states.view(q_shape)?.permute(&[0, 2, 1, 3])?; - let key_states = key_states.view(kv_shape.clone())?.permute(&[0, 2, 1, 3])?; - let value_states = value_states.view(kv_shape)?.permute(&[0, 2, 1, 3])?; - - let offset = kv_cache.as_ref().map(|kv| kv.entries).unwrap_or(0); - let q_dt = query_states.dt(); - let query_states = self - .rope - .schedule(RotaryInput { - input: query_states.full()?, - offset, - })? - .cast(q_dt)?; - let key_states = self - .rope - .schedule(RotaryInput { - input: key_states.full()?, - offset, - })? - .cast(q_dt)?; - - let (key_states, value_states) = if let Some(kv) = kv_cache { - let k_cache = kv.k_cache.cache(key_states, 2, offset)?; - let v_cache = kv.v_cache.cache(value_states, 2, offset)?; - (k_cache, v_cache) - } else { - (key_states, value_states) - }; - - let mut attn_weights = query_states - .full()? - .matmul(key_states.full()?, false, true)? - .mul(self.softmax_scale.clone())? - .cast(q_dt)?; - - if let Some(m) = mask { - let attn_dt = attn_weights.dt(); - attn_weights = attn_weights.add(m.cast(attn_dt)?)?; - } - - let w = attn_weights.full()?.softmax(3)?.cast(value_states.dt())?; - let wv = w - .matmul(value_states, false, false)? - .permute(&[0, 2, 1, 3])?; - let wv = wv.view(shape![batch_size as _, q_len, n_state])?; - self.o.schedule(wv) - } -} - -#[derive(Debug, derive_new::new)] -pub struct DecoderLayer { - pub ln: LayerNorm, - pub self_attn: SelfAttention, - pub mlp: MLP, -} - -#[derive(Debug)] -pub struct DecoderLayerInput { - pub x: Tensor, - pub mask: Option, - pub kv_cache: Option, -} - -impl Module for DecoderLayer { - type Input = DecoderLayerInput; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let DecoderLayerInput { x, mask, kv_cache } = input; - let residual = x.clone(); - let xs = self.ln.schedule(x)?; - let attn_output = self.self_attn.schedule(AttnInput { - input: xs.clone(), - mask, - kv_cache, - })?; - let ff_hs = self.mlp.schedule(xs)?; - attn_output.add(ff_hs)?.add(residual) - } -} - -#[derive(Debug, derive_new::new)] -pub struct TextModel { - pub embedding: Embedding, - pub layers: Vec, - pub ln_post: LayerNorm, - pub lm_head: Linear, - pub kv_cache: KVCache, - pub device: Device, -} - -impl Module for TextModel { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let mut x = input.clone(); - let [_, seq_len, n_state]: [usize; 3] = x.shape().try_into()?; - let mask = if seq_len <= 1 { - None - } else { - Some(Self::generate_mask(seq_len, x.device())?) - }; - - for (i, layer) in self.layers.iter().enumerate() { - let input = DecoderLayerInput { - x, - mask: mask.clone(), - kv_cache: Some(self.kv_cache[i].clone()), - }; - x = layer.schedule(input)?; - } - x = self.ln_post.schedule(x)?; - x = x.slice(&[0..1, seq_len - 1..seq_len, 0..n_state])?; - let logits = self.lm_head.schedule(x)?; - Ok(logits) - } -} - -impl TextModel { - pub fn generate_mask(seq_len: usize, device: &Device) -> anyhow::Result { - let mask: Vec<_> = (0..seq_len) - .flat_map(|i| (0..seq_len).map(move |j| if j > i { f32::NEG_INFINITY } else { 0f32 })) - .collect(); - - Ok(Tensor::from_data( - mask, - shape![seq_len, seq_len], - device.clone(), - )) - } - - pub fn cache_mut(&mut self) -> &mut KVCache { - &mut self.kv_cache - } - pub fn reset(&mut self) { - self.kv_cache.reset(); - } -} diff --git a/crates/ratchet-models/src/moondream/vision_encoder.rs b/crates/ratchet-models/src/moondream/vision_encoder.rs deleted file mode 100644 index 26eb9c3a..00000000 --- a/crates/ratchet-models/src/moondream/vision_encoder.rs +++ /dev/null @@ -1,173 +0,0 @@ -use ratchet::{prelude::shape, rvec, Tensor}; -use ratchet_nn::{LayerNorm, Linear, Module}; - -use super::mlp::MLP; - -#[derive(Debug, derive_new::new)] -pub struct Attention { - n_heads: usize, - dim: usize, - qkv: Linear, - proj: Linear, - scale_factor: Tensor, -} - -impl Module for Attention { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let h_dim = self.dim / self.n_heads; - let [b, n, c]: [usize; 3] = input.shape().try_into()?; - // step 1 - 0, 1, 2, 3, 4 - // step 2 - 0, 2, 1, 3, 4 - // step 3 - 2, 0, 1, 3, 4 - // step 4 - 2, 0, 3, 1, 4 - - // b, n, 3, nh, hd - let mut qkv = self.qkv.schedule(input.clone())?; - // b, 3, n, nh, hd - qkv = qkv - .view(shape![b, n, 3, self.n_heads * h_dim])? - .permute(&[0, 2, 1, 3])?; - // 3, b, n, nh, hd - qkv = qkv - .view(shape![b, 3, n * self.n_heads * h_dim])? - .permute(&[1, 0, 2])?; - // 3, b, nh, n, hd - qkv = qkv - .view(shape![3 * b, n, self.n_heads, h_dim])? - .permute(&[0, 2, 1, 3])? - .view(shape![3, b * self.n_heads * n * h_dim])?; - - let q = qkv - .clone() - .slice(&[0..1, 0..(b * self.n_heads * n * h_dim)])? - .view(shape![b, self.n_heads, n, h_dim])?; - let k = qkv - .clone() - .slice(&[1..2, 0..(b * self.n_heads * n * h_dim)])? - .view(shape![b, self.n_heads, n, h_dim])?; - let v = qkv - .clone() - .slice(&[2..3, 0..(b * self.n_heads * n * h_dim)])? - .view(shape![b, self.n_heads, n, h_dim])?; - - // scaled dot-product attention - let mut attn_weights = q - .full()? - .matmul(k.permute(&[0, 1, 3, 2])?.full()?, false, false)? - .mul(self.scale_factor.clone())?; - attn_weights = attn_weights.softmax(3)?.cast(v.dt())?; - let mut x = attn_weights.matmul(v, false, false)?; - x = x.permute(&[0, 2, 1, 3])?.view(shape![b, n, c])?; - self.proj.schedule(x) - } -} - -#[derive(Debug, derive_new::new)] -pub struct VitBlock { - embed_dim: usize, - attn: Attention, - mlp: MLP, - norm1: LayerNorm, - norm2: LayerNorm, -} - -impl Module for VitBlock { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let x = input - .clone() - .add(self.attn.schedule(self.norm1.schedule(input)?)?)?; - x.clone().add(self.mlp.schedule(self.norm2.schedule(x)?)?) - } -} - -#[derive(Debug, derive_new::new)] -pub struct LinearPatchEmbedding { - linear: Linear, -} - -impl Module for LinearPatchEmbedding { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let [b, c, hp1, wp2]: [usize; 4] = input.shape().try_into()?; - let (p1, p2) = (14, 14); - let (h, w) = (hp1 / p1, wp2 / p2); - // step 1 - 0, 1, 2, 3, 4, 5 - // step 2 - 0, 2, 1, 3, 4, 5 - // step 3 - 0, 2, 1, 4, 3, 5 - // step 4 - 0, 2, 4, 1, 3, 5 - - // b, c, h, p1, w, p2 - let mut x = input - .view(shape![b, c, h, p1 * w * p2])? - .permute(&[0, 2, 1, 3])?; - // b, h, c, p1, w, p2 - x = x - .view(shape![b * h * c, p1, w, p2])? - .permute(&[0, 2, 1, 3])?; - // b, h, c, w, p1, p2 - x = x - .view(shape![b * h, c, w, p1 * p2])? - .permute(&[0, 2, 1, 3])?; - // b, h, w, c, p1, p2 - x = x.view(shape![b, h * w, c * p1 * p2])?; - self.linear.schedule(x) - } -} - -#[derive(Debug, derive_new::new)] -pub struct VisionTransformer { - patch_embed: LinearPatchEmbedding, - pos_embed: Tensor, - blocks: Vec, - norm: LayerNorm, -} - -impl Module for VisionTransformer { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let mut x = self.patch_embed.schedule(input)?; - x = x.clone().add(self.pos_embed.clone())?; - x = self - .blocks - .iter() - .fold(x.clone(), |acc, blk| blk.schedule(acc).unwrap()); - self.norm.schedule(x) - } -} - -#[derive(Debug, derive_new::new)] -pub struct VisionProjection { - mlp: MLP, -} - -impl Module for VisionProjection { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - self.mlp.schedule(input) - } -} - -#[derive(Debug, derive_new::new)] -pub struct VisionEncoder { - projection: VisionProjection, - transformer: VisionTransformer, -} - -impl Module for VisionEncoder { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let transformed = self.transformer.schedule(input)?; - self.projection.schedule(Tensor::cat( - rvec![transformed.clone(), transformed.clone()], - 2, - )?) - } -} diff --git a/crates/ratchet-models/src/registry.rs b/crates/ratchet-models/src/registry.rs index f89181a7..2143ceef 100644 --- a/crates/ratchet-models/src/registry.rs +++ b/crates/ratchet-models/src/registry.rs @@ -6,38 +6,6 @@ #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::wasm_bindgen; -#[derive(Debug, Clone)] -#[cfg_attr( - target_arch = "wasm32", - derive(tsify::Tsify, serde::Serialize, serde::Deserialize), - tsify(from_wasm_abi), - serde(rename_all = "snake_case") -)] -#[cfg_attr(not(target_arch = "wasm32"), derive(clap::ValueEnum))] -pub enum WhisperVariants { - Tiny, - Base, - Small, - Medium, - LargeV2, - LargeV3, - DistilLargeV3, -} - -impl WhisperVariants { - pub fn repo_id(&self) -> &str { - match self { - WhisperVariants::Tiny => "FL33TW00D-HF/whisper-tiny", - WhisperVariants::Base => "FL33TW00D-HF/whisper-base", - WhisperVariants::Small => "FL33TW00D-HF/whisper-small", - WhisperVariants::Medium => "FL33TW00D-HF/whisper-medium", - WhisperVariants::LargeV2 => "FL33TW00D-HF/whisper-large-v2", - WhisperVariants::LargeV3 => "FL33TW00D-HF/whisper-large-v3", - WhisperVariants::DistilLargeV3 => "FL33TW00D-HF/distil-whisper-large-v3", - } - } -} - #[derive(Debug, Clone)] #[cfg_attr( target_arch = "wasm32", @@ -63,40 +31,26 @@ pub enum PhiVariants { )] #[cfg_attr(target_arch = "wasm32", tsify(from_wasm_abi))] pub enum AvailableModels { - Whisper(WhisperVariants), Phi(PhiVariants), - Moondream, } impl AvailableModels { pub fn repo_id(&self) -> String { let id = match self { - AvailableModels::Whisper(w) => w.repo_id(), AvailableModels::Phi(p) => match p { PhiVariants::Phi2 => "FL33TW00D-HF/phi2", PhiVariants::Phi3 => "FL33TW00D-HF/phi3", }, - AvailableModels::Moondream => "ratchet-community/ratchet-moondream-2", }; id.to_string() } pub fn model_id(&self, quantization: Quantization) -> String { let model_stem = match self { - AvailableModels::Whisper(w) => match w { - WhisperVariants::Tiny => "tiny", - WhisperVariants::Base => "base", - WhisperVariants::Small => "small", - WhisperVariants::Medium => "medium", - WhisperVariants::LargeV2 => "large-v2", - WhisperVariants::LargeV3 => "large-v3", - WhisperVariants::DistilLargeV3 => "distil-large-v3", - }, AvailableModels::Phi(p) => match p { PhiVariants::Phi2 => "phi2", PhiVariants::Phi3 => "phi3-mini-4k", }, - AvailableModels::Moondream => "moondream", }; match quantization { Quantization::Q8_0 => format!("{}_q8_0.gguf", model_stem), diff --git a/crates/ratchet-models/src/whisper/config.rs b/crates/ratchet-models/src/whisper/config.rs deleted file mode 100644 index e1a8d5fd..00000000 --- a/crates/ratchet-models/src/whisper/config.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[derive(Debug, Clone, PartialEq, serde::Deserialize)] -pub struct Config { - #[serde(alias = "num_mel_bins")] - pub n_mels: usize, - #[serde(alias = "max_source_positions")] - pub n_audio_ctx: usize, - #[serde(alias = "d_model")] - pub n_audio_state: usize, - #[serde(alias = "encoder_attention_heads")] - pub n_audio_head: usize, - #[serde(alias = "encoder_layers")] - pub n_audio_layer: usize, - #[serde(alias = "vocab_size")] - pub n_vocab: usize, - #[serde(alias = "max_target_positions")] - pub n_text_ctx: usize, - #[serde(alias = "decoder_attention_heads")] - pub n_text_head: usize, - #[serde(alias = "decoder_layers")] - pub n_text_layer: usize, - #[serde(alias = "torch_dtype")] - pub dtype: String, - #[serde(default)] - pub suppress_tokens: Vec, -} diff --git a/crates/ratchet-models/src/whisper/decoder.rs b/crates/ratchet-models/src/whisper/decoder.rs deleted file mode 100644 index d912b46d..00000000 --- a/crates/ratchet-models/src/whisper/decoder.rs +++ /dev/null @@ -1,385 +0,0 @@ -use super::config::Config; -use crate::whisper::residual_block::*; -use half::f16; -use ratchet::{prelude::*, DType, TensorDType}; -use ratchet_loader::gguf::gguf::Header; -use ratchet_nn::{Embedding, KVCache, LayerNorm, Module}; -use std::io::{BufRead, Seek}; - -#[cfg(target_arch = "wasm32")] -use {crate::ratchet_from_gguf_web, crate::TensorMap}; - -#[derive(Debug)] -pub(crate) struct DecoderStem { - pub token_embed: Embedding, - pub pos_embed: Tensor, -} - -impl DecoderStem { - pub fn load( - header: &Header, - reader: &mut R, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.decoder.{}", name); - header.tensor(reader, &key, device) - }; - Self::load_inner(lt) - } - - #[cfg(target_arch = "wasm32")] - pub fn from_web( - header: &Header, - tensor_map: &mut TensorMap, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.decoder.{}", name); - let wt = tensor_map.remove(&key).unwrap(); - ratchet_from_gguf_web(wt, device) - }; - Self::load_inner(lt) - } - - fn load_inner(mut lt: F) -> anyhow::Result - where - F: FnMut(&str) -> anyhow::Result, - { - Ok(Self { - token_embed: Embedding::new(lt("embed_tokens.weight")?), - pos_embed: lt("embed_positions.weight")?, - }) - } -} - -#[derive(Debug)] -pub struct StemInput { - pub tokens: Tensor, - pub offset: usize, -} - -impl Module for DecoderStem { - type Input = StemInput; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let StemInput { tokens, offset } = input; - let num_tokens = tokens.shape()[tokens.rank() - 1]; - let start = offset; - let end = offset + num_tokens; - let mut sliced = self - .pos_embed - .clone() - .slice(&[start..end, 0..self.pos_embed.shape()[1]])?; - - sliced = sliced.cast(self.token_embed.weight.dt().activation_dt())?; - - self.token_embed.schedule(tokens)?.add(sliced) - } -} - -#[derive(Debug)] -pub struct WhisperDecoder { - stem: DecoderStem, - blocks: Vec, - mask: Tensor, - ln_post: LayerNorm, - cache: KVCache, - #[allow(dead_code)] //Should maintain a handle to the device - device: Device, -} - -impl Module for WhisperDecoder { - type Input = [Tensor; 2]; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let [audio_ctx, tokens] = input; - let mut x = self.stem.schedule(StemInput { - tokens, - offset: self.cache.entries(0), - })?; - - for (block_idx, block) in self.blocks.iter().enumerate() { - let block_input = ResidualAttentionBlockInputs { - x, - xa: Some(audio_ctx.clone()), - mask: Some(self.mask.clone()), - cache: Some(self.cache[block_idx].clone()), - }; - x = block.schedule(block_input)?; - } - x = self.ln_post.schedule(x)?; - let logits = self - .stem - .token_embed - .weight - .clone() - .gemm(x, None, false, true, true)? - .full()?; - Ok(logits) - } -} - -impl WhisperDecoder { - pub const MAX_CACHE: usize = 512; - - pub fn cache_mut(&mut self) -> &mut KVCache { - &mut self.cache - } - - pub fn reset(&mut self) { - self.cache.reset(); - } - - fn load_mask(n_ctx: usize, device: &Device) -> Tensor { - let mask: Vec<_> = (0..n_ctx) - .flat_map(|i| { - (0..n_ctx).map(move |j| if j > i { T::neg_infinity() } else { T::zero() }) - }) - .collect(); - Tensor::from_data(mask, shape![n_ctx, n_ctx], device.clone()) - } - - #[cfg(target_arch = "wasm32")] - pub fn from_web( - header: &Header, - config: &Config, - tensor_map: &mut TensorMap, - device: &Device, - ) -> anyhow::Result { - let (n_layers, n_heads) = (config.n_text_layer, config.n_text_head); - let stem = DecoderStem::from_web(header, tensor_map, device)?; - - let blocks = (0..n_layers) - .fold(Vec::with_capacity(n_layers as _), |mut blocks, i| { - blocks.push(ResidualAttentionBlock::from_web( - header, - tensor_map, - i as _, - n_heads as _, - "decoder", - device, - )); - blocks - }) - .into_iter() - .collect::, _>>()?; - - let mut lt = |name: &str| { - let key = format!("model.decoder.layer_norm.{}", name); - let wt = tensor_map.remove(&key).unwrap(); - ratchet_from_gguf_web(wt, device) - }; - - let n_state = config.n_audio_state as _; - - let dt = blocks[0].mlp.activation_dt(); - let mask = match dt { - DType::F16 => Self::load_mask::(config.n_text_ctx as _, device), - DType::F32 => Self::load_mask::(config.n_text_ctx as _, device), - _ => unimplemented!(), - }; - - let cache_shape = shape![1, Self::MAX_CACHE, n_state]; - let cache = match dt { - DType::F16 => KVCache::new::(n_layers as _, cache_shape, device), - DType::F32 => KVCache::new::(n_layers as _, cache_shape, device), - _ => unimplemented!(), - }; - - Ok(Self { - stem, - blocks, - mask, - ln_post: LayerNorm::new(lt("weight")?, Some(lt("bias")?), 1e-5), - cache, - device: device.clone(), - }) - } - - pub fn load( - header: &Header, - config: &Config, - reader: &mut R, - device: &Device, - ) -> anyhow::Result { - let stem = DecoderStem::load(header, reader, device)?; - let (n_layers, n_heads) = (config.n_text_layer, config.n_text_head); - - let blocks = (0..n_layers) - .fold(Vec::with_capacity(n_layers as _), |mut blocks, i| { - blocks.push(ResidualAttentionBlock::load( - header, - reader, - i as _, - n_heads as _, - "decoder", - device, - )); - blocks - }) - .into_iter() - .collect::, _>>()?; - - let mut lt = |name: &str| { - let key = format!("model.decoder.layer_norm.{}", name); - header.tensor(reader, &key, device) - }; - - let n_state = config.n_audio_state as _; - - let dt = blocks[0].mlp.activation_dt(); - let mask = match dt { - DType::F16 => Self::load_mask::(config.n_text_ctx as _, device), - DType::F32 => Self::load_mask::(config.n_text_ctx as _, device), - _ => unimplemented!(), - }; - - let cache_shape = shape![1, Self::MAX_CACHE, n_state]; - let cache = match dt { - DType::F16 => KVCache::new::(n_layers as _, cache_shape, device), - DType::F32 => KVCache::new::(n_layers as _, cache_shape, device), - _ => unimplemented!(), - }; - - Ok(Self { - stem, - blocks, - mask, - ln_post: LayerNorm::new(lt("weight")?, Some(lt("bias")?), 1e-5), - cache, - device: device.clone(), - }) - } -} - -#[cfg(all(test, not(target_arch = "wasm32")))] -mod tests { - use hf_hub::api::sync::Api; - use ndarray::{s, Axis}; - use ndarray_stats::QuantileExt; - use numpy::PyArrayDyn; - use pyo3::{ - prelude::*, - types::{IntoPyDict, PyTuple}, - }; - use ratchet::{shape, Device, DeviceRequest, Tensor}; - use ratchet_loader::gguf::gguf; - use ratchet_nn::Module; - use tokenizers::Tokenizer; - - use crate::whisper::decoder::Config; - use crate::whisper::{ - decoder::WhisperDecoder, - options::{DecodingOptions, DecodingOptionsBuilder}, - }; - - fn log_init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - fn ground_truth(audio_path: &str, options: DecodingOptions) -> anyhow::Result> { - let prg = format!( - r#" -import warnings -warnings.simplefilter("ignore") -import whisper -import numpy as np -def ground(options): - model = whisper.load_model("tiny") - result = model.transcribe(audio="{}", **options) - output_logits = [l.numpy()[np.newaxis] for logits in result["all_logits"] for l in logits] - return output_logits -"#, - audio_path - ); - Python::with_gil(|py| { - let prg = PyModule::from_code(py, &prg, "x.py", "x")?; - let py_args = PyTuple::new(py, [options.into_py_dict(py)]); - let py_result: Vec<&PyArrayDyn> = - prg.getattr("ground")?.call1(py_args)?.extract()?; - Ok(py_result.into_iter().map(Tensor::from).collect::<_>()) - }) - } - - #[test] - fn decoder_matches() -> anyhow::Result<()> { - log_init(); - let api = Api::new().unwrap(); - let model = api.model("FL33TW00D-HF/whisper-tiny".to_string()); - let path = model.get("tiny_f32.gguf").unwrap(); - let config_path = model.get("config.json").unwrap(); - let config: Config = serde_json::from_slice(&std::fs::read(config_path).unwrap()).unwrap(); - println!("MODEL LOADED FROM: {}", path.display()); - - let dataset = api.dataset("FL33TW00D-HF/ratchet-util".to_string()); - let options = DecodingOptionsBuilder::new().build(); - let hs_npy = dataset.get("jfk_tiny_encoder_hs.npy").unwrap(); - let audio_path = dataset.get("jfk.wav").unwrap(); - - let tokenizer_repo = api.model("openai/whisper-tiny".to_string()); - let tokenizer_path = tokenizer_repo.get("tokenizer.json").unwrap(); - let tokenizer = Tokenizer::from_file(tokenizer_path).unwrap(); - - let mut reader = std::io::BufReader::new(std::fs::File::open(path).unwrap()); - let header = gguf::Header::read(&mut reader).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - - let audio_ctx = Tensor::read_npy::(hs_npy, &device)? - .cast(device.compute_precision())? - .resolve()?; - let mut decoder = WhisperDecoder::load(&header, &config, &mut reader, &device)?; - - let mut tokens = vec![50258, 50259, 50359]; - let mut all_tokens = tokens.clone(); - let mut all_logits = vec![]; - let start = std::time::Instant::now(); - while tokens[tokens.len() - 1] != 50257 { - let token_t = - Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let result = decoder - .schedule([audio_ctx.clone(), token_t])? - .resolve_debug()?; - - let our_logits = result.to(&Device::CPU)?; - let nd_logits = our_logits.to_ndarray_view::(); - println!("ND LOGITS: {:?}", nd_logits); - all_logits.push(Tensor::from( - nd_logits - .slice(s![.., .., ..tokenizer.get_vocab_size(true)]) - .to_owned() - .into_dyn(), - )); - - let sliced = nd_logits - .slice(s![.., -1.., ..tokenizer.get_vocab_size(true)]) - .remove_axis(Axis(1)); - decoder.cache_mut().update(tokens.len()); - - tokens = sliced - .map_axis(Axis(1), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - println!("Token: {:?}", tokens); - all_tokens.extend(tokens.clone()); - } - println!("Took: {:?}", start.elapsed()); - - let u32_tokens: Vec<_> = all_tokens.iter().map(|&x| x as u32).collect(); - let decoded = tokenizer.decode(&u32_tokens, true).unwrap(); - println!("All tokens: {:?}", all_tokens); - println!("Decoded: {}", decoded); - - let ground_logits = ground_truth(&audio_path.to_string_lossy(), options)?; - let all_equal = all_logits - .iter() - .zip(ground_logits.iter()) - .all(|(our, their)| their.all_close(our, 1e-4, 1e-4).is_ok()); - - assert!(all_equal); - - Ok(()) - } -} diff --git a/crates/ratchet-models/src/whisper/encoder.rs b/crates/ratchet-models/src/whisper/encoder.rs deleted file mode 100644 index 482ffe3f..00000000 --- a/crates/ratchet-models/src/whisper/encoder.rs +++ /dev/null @@ -1,250 +0,0 @@ -use std::io::{BufRead, Seek}; - -use ratchet::{DType, Device, Tensor}; -use ratchet_loader::gguf::gguf::Header; -use ratchet_nn::{LayerNorm, Module}; - -use super::{ - config::Config, - residual_block::{ResidualAttentionBlock, ResidualAttentionBlockInputs}, -}; - -#[cfg(target_arch = "wasm32")] -use {crate::ratchet_from_gguf_web, crate::TensorMap}; - -#[derive(Debug, derive_new::new)] -struct ConvBlock { - w: Tensor, - b: Tensor, - stride: usize, - padding: usize, -} - -impl Module for ConvBlock { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let input_dt = input.dt(); - input - .conv1d( - self.w.clone().cast(input_dt)?, - Some(self.b.clone().cast(input_dt)?), - self.stride, - self.padding, - )? - .gelu() - } -} - -#[derive(Debug)] -pub(crate) struct EncoderStem { - conv1: ConvBlock, - conv2: ConvBlock, - pos_embed: Tensor, -} - -impl Module for EncoderStem { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - //Currently do CONV in FP32 due to precision issues in kernel - let convolved = self.conv2.schedule(self.conv1.schedule(input.full()?)?)?; - convolved - .permute(&[0, 2, 1])? - .add(self.pos_embed.clone().full()?) - } -} - -impl EncoderStem { - pub fn load( - header: &Header, - reader: &mut R, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.encoder.{}", name); - header.tensor(reader, &key, device) - }; - Self::load_inner(lt) - } - - #[cfg(target_arch = "wasm32")] - pub fn from_web( - header: &Header, - tensor_map: &mut TensorMap, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.encoder.{}", name); - let wt = tensor_map.remove(&key).unwrap(); - ratchet_from_gguf_web(wt, device) - }; - Self::load_inner(lt) - } - - fn load_inner(mut lt: F) -> anyhow::Result - where - F: FnMut(&str) -> anyhow::Result, - { - Ok(Self { - conv1: ConvBlock::new(lt("conv1.weight")?, lt("conv1.bias")?, 1, 1), - conv2: ConvBlock::new(lt("conv2.weight")?, lt("conv2.bias")?, 2, 1), - pos_embed: lt("embed_positions.weight")?, - }) - } -} - -#[derive(Debug)] -pub struct WhisperEncoder { - stem: EncoderStem, - blocks: Vec, - ln_post: LayerNorm, - activation_dt: DType, -} - -impl Module for WhisperEncoder { - type Input = Tensor; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let mut x = self.stem.schedule(input)?.cast(self.activation_dt)?; - - for block in &self.blocks { - let input = ResidualAttentionBlockInputs { - x: x.clone(), - xa: None, - mask: None, - cache: None, - }; - x = block.schedule(input)?; - } - - self.ln_post.schedule(x) - } -} - -impl WhisperEncoder { - #[cfg(target_arch = "wasm32")] - pub fn from_web( - header: &Header, - config: &Config, - tensor_map: &mut TensorMap, - device: &Device, - ) -> anyhow::Result { - let stem = EncoderStem::from_web(header, tensor_map, device)?; - let (n_layers, n_heads) = (config.n_audio_layer, config.n_audio_head); - - let blocks = (0..n_layers) - .fold(Vec::with_capacity(n_layers as _), |mut blocks, i| { - blocks.push(ResidualAttentionBlock::from_web( - header, - tensor_map, - i as _, - n_heads as _, - "encoder", - device, - )); - blocks - }) - .into_iter() - .collect::, _>>()?; - - let mut lt = |name: &str| { - let key = format!("model.encoder.layer_norm.{}", name); - let wt = tensor_map.remove(&key).unwrap(); - ratchet_from_gguf_web(wt, device) - }; - - let activation_dt = blocks[0].mlp.activation_dt(); - - Ok(Self { - stem, - blocks, - ln_post: LayerNorm::new(lt("weight")?, Some(lt("bias")?), 1e-5), - activation_dt, - }) - } - - pub fn load( - header: &Header, - config: &Config, - reader: &mut R, - device: &Device, - ) -> anyhow::Result { - let stem = EncoderStem::load(header, reader, device)?; - let (n_layers, n_heads) = (config.n_audio_layer, config.n_audio_head); - - let blocks = (0..n_layers) - .fold(Vec::with_capacity(n_layers as _), |mut blocks, i| { - blocks.push(ResidualAttentionBlock::load( - header, - reader, - i as _, - n_heads as _, - "encoder", - device, - )); - blocks - }) - .into_iter() - .collect::, _>>()?; - - let activation_dt = blocks[0].mlp.activation_dt(); - - let mut lt = |name: &str| { - let key = format!("model.encoder.layer_norm.{}", name); - header.tensor(reader, &key, device) - }; - - Ok(Self { - stem, - blocks, - ln_post: LayerNorm::new(lt("weight")?, Some(lt("bias")?), 1e-5), - activation_dt, - }) - } -} - -#[cfg(all(test, not(target_arch = "wasm32")))] -mod tests { - use hf_hub::api::sync::Api; - use ratchet::{Device, DeviceRequest, Tensor}; - use ratchet_loader::gguf::gguf; - use ratchet_nn::Module; - - use crate::whisper::{config::Config, encoder::WhisperEncoder}; - - fn log_init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - #[test] - fn encoder_matches() -> anyhow::Result<()> { - log_init(); - let api = Api::new().unwrap(); - let model = api.model("FL33TW00D-HF/whisper-tiny".to_string()); - let model_path = model.get("tiny_f32.gguf").unwrap(); - println!("Path: {}", model_path.display()); - let config_path = model.get("config.json").unwrap(); - - let dataset = api.dataset("FL33TW00D-HF/ratchet-util".to_string()); - let input_npy = dataset.get("jfk_tiny_encoder_input.npy").unwrap(); - let ground_npy = dataset.get("jfk_tiny_encoder_hs.npy").unwrap(); - - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path).unwrap()); - let header = gguf::Header::read(&mut reader).unwrap(); - let config: Config = serde_json::from_slice(&std::fs::read(config_path).unwrap()).unwrap(); - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - - let encoder = WhisperEncoder::load(&header, &config, &mut reader, &device)?; - let input = Tensor::read_npy::(input_npy, &device)?; - - let result = encoder.schedule(input)?.full()?.resolve()?; - let ours = result.to(&Device::CPU)?; - let ground = Tensor::read_npy::(ground_npy, &Device::CPU)?; - println!("OURS: {:#?}", ours); - println!("Ground: {:#?}", ground); - ground.all_close(&ours, 1e-3, 1e-3)?; - - Ok(()) - } -} diff --git a/crates/ratchet-models/src/whisper/logit_mutators/mod.rs b/crates/ratchet-models/src/whisper/logit_mutators/mod.rs deleted file mode 100644 index bf6589ab..00000000 --- a/crates/ratchet-models/src/whisper/logit_mutators/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -mod timestamp_rules; -pub use timestamp_rules::*; - -use crate::whisper::tokenizer::WhisperTokenizer; -use ratchet::Tensor; - -pub trait LogitMutator { - fn apply( - &self, - logits: Tensor, - tokenizer: &WhisperTokenizer, - tokens: Option<&Tensor>, - ) -> anyhow::Result; -} diff --git a/crates/ratchet-models/src/whisper/logit_mutators/timestamp_rules.rs b/crates/ratchet-models/src/whisper/logit_mutators/timestamp_rules.rs deleted file mode 100644 index bb50ab46..00000000 --- a/crates/ratchet-models/src/whisper/logit_mutators/timestamp_rules.rs +++ /dev/null @@ -1,97 +0,0 @@ -use ndarray::s; -use ndarray_stats::QuantileExt; -use ratchet::{NDArrayExt, Tensor}; - -use super::LogitMutator; -use crate::whisper::tokenizer::WhisperTokenizer; - -#[derive(Debug, derive_new::new)] -pub struct ApplyTimestampRules { - pub sample_begin: usize, - pub max_initial_timestamp_index: Option, -} - -impl LogitMutator for ApplyTimestampRules { - fn apply( - &self, - logits: Tensor, - tokenizer: &WhisperTokenizer, - tokens: Option<&Tensor>, - ) -> anyhow::Result { - let nd_tokens = tokens.unwrap().clone().into_ndarray::(); - let mut nd_logits = logits.into_ndarray::(); - - nd_logits - .slice_mut(s![.., tokenizer.notimestamps() as usize]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - for k in 0..nd_tokens.shape()[0] { - let sampled_tokens = nd_tokens.slice(s![k, self.sample_begin..]); - let sample_len = sampled_tokens.len(); - - let last_was_timestamp = !sampled_tokens.is_empty() - && sampled_tokens[sample_len - 1] >= tokenizer.timestamp_begin(); - let penultimate_was_timestamp = sampled_tokens.len() < 2 - || sampled_tokens[sample_len - 2] >= tokenizer.timestamp_begin(); - - if last_was_timestamp { - if penultimate_was_timestamp { - nd_logits - .slice_mut(s![k, tokenizer.timestamp_begin()..]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - } else { - nd_logits - .slice_mut(s![k, ..WhisperTokenizer::EOT]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - } - } - - let timestamps = sampled_tokens - .iter() - .filter(|x| **x >= tokenizer.timestamp_begin()) - .collect::>(); - - if !timestamps.is_empty() { - // timestamps shouldn't decrease; forbid timestamp tokens smaller than the last - // also force each segment to have a nonzero length, to prevent infinite looping - let timestamp_last = if last_was_timestamp && !penultimate_was_timestamp { - *timestamps[timestamps.len() - 1] - } else { - timestamps[timestamps.len() - 1] + 1 - }; - nd_logits - .slice_mut(s![k, tokenizer.timestamp_begin()..timestamp_last]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - } - } - if nd_tokens.shape()[1] == self.sample_begin { - // suppress generating non-timestamp tokens at the beginning - nd_logits - .slice_mut(s![.., ..tokenizer.timestamp_begin()]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - if self.max_initial_timestamp_index.is_some() { - let last_allowed = (tokenizer.timestamp_begin() as usize) - + self.max_initial_timestamp_index.unwrap(); - nd_logits - .slice_mut(s![.., last_allowed + 1..]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - } - } - - let logprobs = nd_logits.log_softmax(1); - for _k in 0..nd_tokens.shape()[0] { - let timestamp_logprob = logprobs - .slice(s![.., tokenizer.timestamp_begin()..]) - .logsumexp(1); - let text_logprobs = logprobs.slice(s![.., ..tokenizer.timestamp_begin()]); - let max_text_token_logprob = text_logprobs.max()?; - if timestamp_logprob > *max_text_token_logprob { - nd_logits - .slice_mut(s![.., ..tokenizer.timestamp_begin()]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - } - } - Ok(Tensor::from(nd_logits)) - } -} diff --git a/crates/ratchet-models/src/whisper/mha.rs b/crates/ratchet-models/src/whisper/mha.rs deleted file mode 100644 index faabdeae..00000000 --- a/crates/ratchet-models/src/whisper/mha.rs +++ /dev/null @@ -1,128 +0,0 @@ -use half::f16; -use num::traits::real::Real; -use ratchet::{rvec, shape, Tensor}; -use ratchet_nn::{KVEntry, Linear, Module}; - -#[derive(Debug)] -pub struct MultiHeadAttention { - q: Linear, - k: Linear, - v: Linear, - o: Linear, - n_heads: usize, - dk: Tensor, -} - -impl MultiHeadAttention { - pub fn new(q: Linear, k: Linear, v: Linear, o: Linear, n_heads: usize) -> MultiHeadAttention { - let n_state = q.w.shape()[1]; - let dk = match q.w.dt().activation_dt() { - ratchet::DType::F16 => { - let dk = f16::from_f32((n_state / n_heads) as f32); - Tensor::from_data( - [dk.powf(f16::from_f32(-0.25))], - shape![1], - q.w.device().clone(), - ) - } - ratchet::DType::F32 => { - let dk = (n_state / n_heads) as f32; - Tensor::from_data([dk.powf(-0.25)], shape![1], q.w.device().clone()) - } - _ => unimplemented!(), - }; - MultiHeadAttention { - q, - k, - v, - o, - n_heads, - dk, - } - } -} - -#[derive(Debug, derive_new::new)] -pub struct MHAInputs { - x: Tensor, - xa: Option, - mask: Option, - cache: Option, - is_causal: bool, -} - -impl Module for MultiHeadAttention { - type Input = MHAInputs; - - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let MHAInputs { - x, - xa, - mask, - cache, - is_causal, - } = input; - - let q = self.q.schedule(x.clone())?; - - let to_project = xa.unwrap_or(x); - let k = self.k.schedule(to_project.clone())?; - let v = self.v.schedule(to_project)?; - - let (k, v) = if let Some(kv) = cache { - let prev_entries = kv.entries; - let k_cache = kv.k_cache.cache(k, 1, prev_entries)?; - let v_cache = kv.v_cache.cache(v, 1, prev_entries)?; - (k_cache, v_cache) - } else { - (k, v) - }; - - self.qkv_attention(q, k, v, mask, is_causal) - } -} - -impl MultiHeadAttention { - fn qkv_attention( - &self, - q: Tensor, - k: Tensor, - v: Tensor, - mask: Option, - is_causal: bool, - ) -> anyhow::Result { - let [bs, n_ctx, n_state]: [usize; 3] = q.shape().try_into()?; - let [k0, k1, _]: [usize; 3] = k.shape().try_into()?; - let [v0, v1, _]: [usize; 3] = v.shape().try_into()?; - let q_dt = q.dt(); - - let hdim = n_state / self.n_heads; - - let qs = shape![bs, n_ctx, self.n_heads, hdim]; - let ks = shape![k0, k1, self.n_heads, hdim]; - let vs = shape![v0, v1, self.n_heads, hdim]; - - let q = q.view(qs)?.permute(&[0, 2, 1, 3])?.mul(self.dk.clone())?; - let k = k.view(ks)?.permute(&[0, 2, 3, 1])?.mul(self.dk.clone())?; - let v = v.view(vs)?.permute(&[0, 2, 1, 3])?; - - let mut qk = q.matmul(k, false, false)?; - - if let Some(m) = mask { - let prepared_mask = if is_causal { - m.slice(&[0..n_ctx, 0..n_ctx])? - } else { - m.clone() - }; - qk = qk.add(prepared_mask)?; - } - qk = qk.full()?; - - let w = qk.softmax(3)?.cast(q_dt)?; - - let s = shape![bs, n_ctx, n_state]; - let wv = w.matmul(v, false, false)?.permute(&[0, 2, 1, 3])?.view(s)?; - - self.o.schedule(wv) - } -} diff --git a/crates/ratchet-models/src/whisper/mlp.rs b/crates/ratchet-models/src/whisper/mlp.rs deleted file mode 100644 index 66af4949..00000000 --- a/crates/ratchet-models/src/whisper/mlp.rs +++ /dev/null @@ -1,23 +0,0 @@ -use ratchet::Tensor; -use ratchet_nn::{Linear, Module}; - -#[derive(Debug, derive_new::new)] -pub struct MLP { - l1: Linear, - l2: Linear, -} - -impl MLP { - pub fn activation_dt(&self) -> ratchet::DType { - self.l1.w.dt().activation_dt() - } -} - -impl Module for MLP { - type Input = Tensor; - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let input_dt = input.dt(); - self.l2 - .schedule(self.l1.schedule(input)?.full()?.gelu()?.cast(input_dt)?) - } -} diff --git a/crates/ratchet-models/src/whisper/mod.rs b/crates/ratchet-models/src/whisper/mod.rs deleted file mode 100644 index bba35c1e..00000000 --- a/crates/ratchet-models/src/whisper/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -mod config; -mod decoder; -mod encoder; -mod logit_mutators; -mod mha; -mod mlp; -mod model; -mod residual_block; -mod samplers; -mod spectrogram; -mod task; - -pub mod options; -pub mod tokenizer; -pub mod transcribe; -pub mod transcript; - -pub use config::Config; -pub use decoder::WhisperDecoder; -pub use encoder::WhisperEncoder; -pub use model::Whisper; diff --git a/crates/ratchet-models/src/whisper/model.rs b/crates/ratchet-models/src/whisper/model.rs deleted file mode 100644 index 90541936..00000000 --- a/crates/ratchet-models/src/whisper/model.rs +++ /dev/null @@ -1,293 +0,0 @@ -use ratchet::{shape, Device, Tensor}; -use ratchet_loader::gguf::gguf::Header; -use ratchet_nn::Module; - -use ndarray::{s, Dimension}; -use ndarray_stats::QuantileExt; -use ratchet::NDArrayExt; - -#[cfg(not(target_arch = "wasm32"))] -use { - hf_hub::api::sync::Api, - std::io::{BufRead, Seek}, -}; - -#[cfg(target_arch = "wasm32")] -use {crate::TensorMap, ratchet_hub::ApiBuilder, ratchet_hub::RepoType, wasm_bindgen::prelude::*}; - -use crate::registry::WhisperVariants; -use crate::whisper::{options::Language, task::DecodingTask, tokenizer::WhisperTokenizer}; - -use super::encoder::WhisperEncoder; -use super::spectrogram::SpectrogramGenerator; -use super::{config::Config, decoder::WhisperDecoder}; - -#[derive(Debug)] -pub struct Whisper { - pub specgen: SpectrogramGenerator, - pub encoder: WhisperEncoder, - pub decoder: WhisperDecoder, - pub config: Config, - pub device: Device, -} - -impl Whisper { - #[cfg(not(target_arch = "wasm32"))] - pub fn load( - header: Header, - variant: WhisperVariants, - reader: &mut R, - device: Device, - ) -> anyhow::Result { - let mel_fname = match variant { - WhisperVariants::DistilLargeV3 | WhisperVariants::LargeV3 => "melfilters128.bytes", - _ => "melfilters.bytes", - }; - let mel_bytes = Self::fetch_resource(&variant, mel_fname)?; - let mut mel_filters = vec![0f32; mel_bytes.len() / 4]; - ::read_f32_into( - &mel_bytes, - &mut mel_filters, - ); - let specgen = SpectrogramGenerator::new(mel_filters); - - let config: Config = - serde_json::from_slice(&Self::fetch_resource(&variant, "config.json")?)?; - let encoder = WhisperEncoder::load(&header, &config, reader, &device)?; - let decoder = WhisperDecoder::load(&header, &config, reader, &device)?; - - Ok(Self { - specgen, - encoder, - decoder, - config, - device, - }) - } - - #[cfg(target_arch = "wasm32")] - pub async fn from_web( - header: Header, - mut tensors: TensorMap, - variant: WhisperVariants, - ) -> anyhow::Result { - let device = Device::request_device(ratchet::DeviceRequest::GPU).await?; - let mel_fname = match variant { - WhisperVariants::DistilLargeV3 | WhisperVariants::LargeV3 => "melfilters128.bytes", - _ => "melfilters.bytes", - }; - let mel_bytes = Self::fetch_resource(&variant, mel_fname).await.unwrap(); - let mut mel_filters = vec![0f32; mel_bytes.len() / 4]; - ::read_f32_into( - &mel_bytes, - &mut mel_filters, - ); - let specgen = SpectrogramGenerator::new(mel_filters); - - let config: Config = - serde_json::from_slice(&Self::fetch_resource(&variant, "config.json").await.unwrap())?; - - let encoder = WhisperEncoder::from_web(&header, &config, &mut tensors, &device)?; - let decoder = WhisperDecoder::from_web(&header, &config, &mut tensors, &device)?; - - Ok(Self { - specgen, - encoder, - decoder, - config, - device, - }) - } - - #[cfg(target_arch = "wasm32")] - pub async fn fetch_resource( - variant: &WhisperVariants, - resource: &str, - ) -> Result, JsValue> { - let repo_id = variant.repo_id(); - let model_repo = ApiBuilder::from_hf(repo_id, RepoType::Model).build(); - let resp = model_repo.get(resource).await; - match resp { - Ok(data) => Ok(data.to_vec()), - Err(_) => Err(JsError::new(format!("Failed to fetch resource").as_str()).into()), - } - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn fetch_resource(variant: &WhisperVariants, resource: &str) -> anyhow::Result> { - let api = Api::new().unwrap(); - let repo_id = variant.repo_id(); - - let repo = api.model(repo_id.to_string()); - Ok(std::fs::read(repo.get(resource).unwrap())?) - } -} - -impl Whisper { - pub fn is_multilingual(&self) -> bool { - self.config.n_vocab >= 51865 - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn detect_language(&mut self, _mel: Tensor) -> anyhow::Result { - panic!("DETECT LANGUAGE NOT IMPLEMENTED"); - let audio_ctx = self.encoder.schedule(_mel)?.resolve()?; - let sot = Tensor::from_data([WhisperTokenizer::SOT], shape![1, 1], self.device.clone()); - - let logits = self.decoder.schedule([audio_ctx, sot])?.full()?.resolve()?; - self.decoder.reset(); - - let cpu_logits = logits.to(&Device::CPU)?; - println!("LOGITS: {:?}", cpu_logits); - let logits = DecodingTask::slice_logits(cpu_logits, self.config.n_vocab); - - let device = logits.device().clone(); - let mut nd_logits = logits.into_ndarray::(); - - let languages_end = if self.config.n_vocab == 51865 { - 50358 - } else if self.config.n_vocab == 51866 { - 50359 - } else { - panic!("Unsupported number of tokens") - }; - - nd_logits - .slice_mut(s![.., ..WhisperTokenizer::LANGUAGES_BEGIN]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - nd_logits - .slice_mut(s![.., languages_end..]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - let language_tokens_probs = nd_logits.softmax(nd_logits.ndim() - 1); - - let argmax_dims = language_tokens_probs.argmax_skipnan().unwrap(); - let argmax: u32 = argmax_dims[argmax_dims.ndim() - 1] as _; - let lang_t = Tensor::from_data([argmax], shape![1], device); - - Ok(Language::Token(lang_t.item())) - } - - #[cfg(target_arch = "wasm32")] - pub async fn detect_language(&mut self, mel: Tensor) -> anyhow::Result { - panic!("DETECT LANGUAGE NOT IMPLEMENTED"); - let audio_ctx = self.encoder.schedule(mel)?.resolve()?; - let sot = Tensor::from_data([WhisperTokenizer::SOT], shape![1, 1], self.device.clone()); - - let logits = self.decoder.schedule([audio_ctx, sot])?.resolve()?; - self.decoder.reset(); - - let cpu_logits = logits.to(&Device::CPU).await?; - let logits = DecodingTask::slice_logits(cpu_logits, self.config.n_vocab as usize); - - let device = logits.device().clone(); - let mut nd_logits = logits.into_ndarray::(); - - let languages_end = if self.config.n_vocab == 51865 { - 50358 - } else if self.config.n_vocab == 51866 { - 50359 - } else { - panic!("Unsupported number of tokens") - }; - - nd_logits - .slice_mut(s![.., ..WhisperTokenizer::LANGUAGES_BEGIN]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - nd_logits - .slice_mut(s![.., languages_end..]) - .map_inplace(move |el| *el = f32::NEG_INFINITY); - - let language_tokens_probs = nd_logits.softmax(nd_logits.ndim() - 1); - - let argmax_dims = language_tokens_probs.argmax_skipnan().unwrap(); - let argmax: u32 = argmax_dims[argmax_dims.ndim() - 1] as _; - let lang_t = Tensor::from_data([argmax], shape![1], device); - - Ok(Language::Token(lang_t.item())) - } -} - -#[cfg(all(test, not(target_arch = "wasm32")))] -mod tests { - use std::path::PathBuf; - - use hf_hub::api::sync::Api; - use ratchet::{Device, DeviceRequest}; - use ratchet_loader::gguf::gguf; - - use crate::{ - registry::WhisperVariants, - whisper::{ - model::Whisper, options::DecodingOptionsBuilder, transcribe::transcribe, - transcript::StreamedSegment, - }, - }; - - fn log_init() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - fn load_sample(path: PathBuf) -> Vec { - let mut reader = hound::WavReader::open(path).unwrap(); - reader - .samples::() - .map(|x| x.unwrap() as f32 / 32768.0) - .collect::>() - } - - const MM0_Q8_GROUND: [u32; 196] = [ - 50364, 639, 307, 264, 4532, 3479, 13460, 264, 881, 34674, 5932, 30340, 295, 5116, 2065, - 5729, 13, 50524, 50524, 1981, 472, 575, 12023, 4365, 337, 257, 1702, 6034, 3028, 1523, - 1804, 4651, 4532, 3479, 50668, 50668, 8963, 6742, 300, 1619, 257, 3804, 5214, 2610, 5214, - 6383, 2643, 5214, 293, 544, 2176, 50816, 50816, 8963, 21800, 281, 747, 604, 1081, 293, 456, - 366, 867, 34674, 3190, 281, 862, 365, 309, 1184, 50948, 50948, 472, 1487, 365, 1080, 1065, - 2121, 11377, 4532, 3479, 5864, 293, 1019, 5456, 4122, 300, 51084, 51084, 544, 20095, 1286, - 13, 51134, 51134, 30062, 264, 13436, 574, 412, 264, 10155, 35310, 587, 264, 3874, 14701, - 1068, 281, 264, 7267, 3096, 2541, 428, 1032, 51264, 51264, 281, 818, 5675, 5300, 264, 281, - 3623, 293, 613, 1081, 300, 311, 3318, 1214, 281, 1254, 257, 4532, 3479, 51404, 51404, 1002, - 13, 51454, 51454, 1222, 3479, 8963, 6742, 300, 311, 1270, 257, 7195, 5870, 370, 6239, - 13600, 370, 309, 1177, 380, 51552, 51552, 321, 2607, 1488, 68, 322, 257, 8963, 264, 16026, - 4532, 8379, 293, 4532, 3479, 8963, 6742, 300, 311, 51696, 50364, 3718, 14759, 490, 3114, - 996, 264, 4356, 436, 366, 264, 1101, 436, 366, 13, 50500, - ]; - - #[test] - pub fn whisper_end_to_end() { - log_init(); - let api = Api::new().unwrap(); - let model = api.model("FL33TW00D-HF/whisper-tiny".to_string()); - let model_path = model.get("tiny_q8_0.gguf").unwrap(); - let variant = WhisperVariants::Tiny; - println!("PATH: {:?}", model_path.display()); - - let dataset = api.dataset("FL33TW00D-HF/ratchet-util".to_string()); - let audio_path = dataset.get("mm0.wav").unwrap(); - let samples = load_sample(audio_path); - - let options = DecodingOptionsBuilder::new() - .language("en".to_string()) - .build(); - let mut reader = std::io::BufReader::new(std::fs::File::open(model_path).unwrap()); - let header = gguf::Header::read(&mut reader).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).unwrap(); - - let mut whisper = Whisper::load(header, variant, &mut reader, device).unwrap(); - - let empty_cb: Option = None; - let transcript = transcribe(&mut whisper, samples, options, empty_cb).unwrap(); - - let all_tokens = transcript - .segments - .iter() - .flat_map(|s| s.tokens.clone().into_iter()) - .collect::>(); - - println!("{}", transcript.formatted.unwrap()); - println!("Processing time: {:?}", transcript.processing_time); - //assert_eq!(all_tokens, MM0_Q8_GROUND); - } -} diff --git a/crates/ratchet-models/src/whisper/options.rs b/crates/ratchet-models/src/whisper/options.rs deleted file mode 100644 index 0f5ade77..00000000 --- a/crates/ratchet-models/src/whisper/options.rs +++ /dev/null @@ -1,310 +0,0 @@ -use crate::whisper::tokenizer::WhisperTokenizer; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - -#[cfg_attr(target_arch = "wasm32", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone)] -pub enum Language { - String(String), - Token(i32), -} - -#[cfg_attr(target_arch = "wasm32", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone)] -pub enum Prompt { - Text(String), - Tokens(Vec), -} - -#[cfg_attr( - target_arch = "wasm32", - wasm_bindgen, - derive(serde::Serialize, serde::Deserialize) -)] -#[derive(Debug, Clone, Copy)] -pub enum Task { - Transcribe, - Translate, -} - -impl Task { - pub fn as_token(&self, tokenizer: &WhisperTokenizer) -> i32 { - match self { - Task::Transcribe => tokenizer.transcribe(), - Task::Translate => tokenizer.translate(), - } - } -} - -#[allow(dead_code)] -#[cfg_attr( - target_arch = "wasm32", - wasm_bindgen, - derive(serde::Serialize, serde::Deserialize) -)] -#[derive(Debug, Clone)] -pub struct DecodingOptions { - pub(crate) task: Task, // default: "transcribe" - pub(crate) language: Option, // default: None - pub(crate) temperature: f32, // default: 0.0 - pub(crate) sample_len: Option, // default: None - pub(crate) best_of: Option, // default: None - pub(crate) beam_size: Option, // default: None - pub(crate) patience: Option, // default: None - pub(crate) length_penalty: Option, // default: None - pub(crate) prompt: Option, // default: None - pub(crate) prefix: Option, // default: None - pub(crate) suppress_tokens: Option>, // default: Some("-1".to_string()) - pub(crate) suppress_blank: bool, // default: true - pub(crate) without_timestamps: bool, // default: false - pub(crate) max_initial_timestamp: Option, // default: Some(1.0) - pub(crate) time_offset: Option, // default: None -} - -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -pub struct DecodingOptionsBuilder { - task: Option, - language: Option, - temperature: Option, - sample_len: Option, - best_of: Option, - beam_size: Option, - patience: Option, - length_penalty: Option, - prompt: Option, - prefix: Option, - suppress_tokens: Option>, - suppress_blank: Option, - without_timestamps: Option, - max_initial_timestamp: Option, - time_offset: Option, -} - -impl Default for DecodingOptionsBuilder { - fn default() -> Self { - Self::new() - } -} - -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -impl DecodingOptionsBuilder { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] - pub fn new() -> DecodingOptionsBuilder { - DecodingOptionsBuilder { - task: Some(Task::Transcribe), - language: Some(String::from("en")), - temperature: Some(0.0), - sample_len: None, - best_of: None, - beam_size: None, - patience: None, - length_penalty: None, - prompt: None, - prefix: None, - suppress_tokens: Some(vec![-1]), - suppress_blank: Some(true), - max_initial_timestamp: Some(1.0), - without_timestamps: Some(false), - time_offset: None, - } - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setTask"))] - pub fn task(mut self, task: Task) -> Self { - self.task = Some(task); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setLanguage"))] - pub fn language(mut self, language: String) -> Self { - self.language = Some(language); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setTemperature"))] - pub fn temperature(mut self, temperature: f32) -> Self { - self.temperature = Some(temperature); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setSampleLen"))] - pub fn sample_len(mut self, sample_len: u32) -> Self { - self.sample_len = Some(sample_len); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setBestOf"))] - pub fn best_of(mut self, best_of: u32) -> Self { - self.best_of = Some(best_of); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setBeamSize"))] - pub fn beam_size(mut self, beam_size: u32) -> Self { - self.beam_size = Some(beam_size); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setPatience"))] - pub fn patience(mut self, patience: f32) -> Self { - self.patience = Some(patience); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setLengthPenalty"))] - pub fn length_penalty(mut self, length_penalty: f32) -> Self { - self.length_penalty = Some(length_penalty); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setPrompt"))] - pub fn prompt(mut self, prompt: String) -> Self { - self.prompt = Some(prompt); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setPrefix"))] - pub fn prefix(mut self, prefix: String) -> Self { - self.prefix = Some(prefix); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setSuppressTokens"))] - pub fn suppress_tokens(mut self, suppress_tokens: Vec) -> Self { - self.suppress_tokens = Some(suppress_tokens); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setSuppressBlank"))] - pub fn suppress_blank(mut self, suppress_blank: bool) -> Self { - self.suppress_blank = Some(suppress_blank); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setWithoutTimestamps"))] - pub fn without_timestamps(mut self, without_timestamps: bool) -> Self { - self.without_timestamps = Some(without_timestamps); - self - } - - #[cfg_attr( - target_arch = "wasm32", - wasm_bindgen(js_name = "setMaxInitialTimestamp") - )] - pub fn max_initial_timestamp(mut self, max_initial_timestamp: f32) -> Self { - self.max_initial_timestamp = Some(max_initial_timestamp); - self - } - - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = "setTimeOffset"))] - pub fn time_offset(mut self, time_offset: f64) -> Self { - self.time_offset = Some(time_offset); - self - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn build(&self) -> DecodingOptions { - DecodingOptions { - task: self.task.unwrap_or(Task::Transcribe), - language: self.language.clone().map(Language::String), - temperature: self.temperature.unwrap_or(0.0), - sample_len: self.sample_len, - best_of: self.best_of, - beam_size: self.beam_size, - patience: self.patience, - length_penalty: self.length_penalty, - prompt: self.prompt.clone().map(Prompt::Text), - prefix: self.prefix.clone(), - suppress_tokens: self.suppress_tokens.clone(), - suppress_blank: self.suppress_blank.unwrap_or(true), - without_timestamps: self.without_timestamps.unwrap_or(false), - max_initial_timestamp: self.max_initial_timestamp, - time_offset: self.time_offset, - } - } - - #[cfg(target_arch = "wasm32")] - pub fn build(&self) -> JsValue { - let options = DecodingOptions { - task: self.task.unwrap_or(Task::Transcribe), - language: self.language.clone().map(Language::String), - temperature: self.temperature.unwrap_or(0.0), - sample_len: self.sample_len, - best_of: self.best_of, - beam_size: self.beam_size, - patience: self.patience, - length_penalty: self.length_penalty, - prompt: self.prompt.clone().map(Prompt::Text), - prefix: self.prefix.clone(), - suppress_tokens: self.suppress_tokens.clone(), - suppress_blank: self.suppress_blank.unwrap_or(true), - without_timestamps: self.without_timestamps.unwrap_or(false), - max_initial_timestamp: self.max_initial_timestamp, - time_offset: self.time_offset, - }; - serde_wasm_bindgen::to_value(&options).unwrap() - } -} - -cfg_if::cfg_if! { - if #[cfg(all(not(target_arch = "wasm32"), test))] { - use pyo3::types::{IntoPyDict, PyDict}; - use pyo3::Python; - use pyo3::types::PyString; - use pyo3::IntoPy; - use pyo3::PyObject; - - impl IntoPy for Task { - fn into_py(self, py: Python) -> PyObject { - let task = match self { - Task::Transcribe => "transcribe", - Task::Translate => "translate", - }; - PyString::new(py, task).into() - } - } - - impl IntoPy for Language { - fn into_py(self, py: Python) -> PyObject { - let language = match self { - Language::String(s) => s, - Language::Token(t) => t.to_string(), - }; - PyString::new(py, &language).into() - } - } - - impl IntoPy for Prompt { - fn into_py(self, py: Python) -> PyObject { - match self { - Prompt::Text(s) => PyString::new(py, &s).into(), - Prompt::Tokens(t) => t.into_py(py), - } - } - } - - impl IntoPyDict for DecodingOptions { - fn into_py_dict(self, py: Python) -> &pyo3::types::PyDict { - let dict = PyDict::new(py); - let supress_tokens_string = self.suppress_tokens.map(|v| v.iter().map(|t| t.to_string()).collect::>().join(",")); - - let _ = dict.set_item("task", self.task.into_py(py)); - let _ = dict.set_item("language", self.language.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("temperature", self.temperature.into_py(py)); - let _ = dict.set_item("sample_len", self.sample_len.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("best_of", self.best_of.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("beam_size", self.beam_size.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("patience", self.patience.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("length_penalty", self.length_penalty.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("prompt", self.prompt.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("prefix", self.prefix.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("suppress_tokens", supress_tokens_string.map_or_else(|| py.None(), |v| v.into_py(py))); - let _ = dict.set_item("suppress_blank", self.suppress_blank.into_py(py)); - let _ = dict.set_item("without_timestamps", self.without_timestamps.into_py(py)); - let _ = dict.set_item("max_initial_timestamp", self.max_initial_timestamp.map_or_else(|| py.None(), |v| v.into_py(py))); - - dict - } - } - } -} diff --git a/crates/ratchet-models/src/whisper/residual_block.rs b/crates/ratchet-models/src/whisper/residual_block.rs deleted file mode 100644 index 97d0fde3..00000000 --- a/crates/ratchet-models/src/whisper/residual_block.rs +++ /dev/null @@ -1,161 +0,0 @@ -use super::{mha::*, mlp::MLP}; -use ratchet::{Device, Tensor}; -use ratchet_loader::gguf::gguf::Header; -use ratchet_nn::{KVEntry, LayerNorm, Linear, Module}; -use std::io::{BufRead, Seek}; - -#[cfg(target_arch = "wasm32")] -use {crate::ratchet_from_gguf_web, crate::TensorMap}; - -#[derive(Debug)] -pub struct ResidualAttentionBlock { - attn_ln: LayerNorm, - attn: MultiHeadAttention, - x_attn_ln: Option, - x_attn: Option, - mlp_ln: LayerNorm, - pub mlp: MLP, -} - -#[derive(Debug, derive_new::new)] -pub struct ResidualAttentionBlockInputs { - pub x: Tensor, - pub xa: Option, - pub mask: Option, - pub cache: Option, -} - -impl Module for ResidualAttentionBlock { - type Input = ResidualAttentionBlockInputs; - fn schedule(&self, input: Self::Input) -> anyhow::Result { - let ResidualAttentionBlockInputs { x, xa, mask, cache } = input; - - let attn_ln = self.attn_ln.schedule(x.clone())?; - let self_attn = - self.attn - .schedule(MHAInputs::new(attn_ln, None, mask.clone(), cache, true))?; - - let mut attn = x.add(self_attn)?; - - if let Some(ref xa_blck) = self.x_attn { - if let Some(xa_ln) = &self.x_attn_ln { - let x_attn_ln = xa_ln.schedule(attn.clone())?; - let x_attn = - xa_blck.schedule(MHAInputs::new(x_attn_ln, xa.clone(), None, None, false))?; - attn = x_attn.add(attn.clone())?; - } - } - let mlp_ln = self.mlp_ln.schedule(attn.clone())?; - let mlp = self.mlp.schedule(mlp_ln)?; - mlp.add(attn) - } -} - -impl ResidualAttentionBlock { - pub fn load( - header: &Header, - reader: &mut R, - layer_index: usize, - n_heads: usize, - prefix: &str, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.{}.layers.{}.{}", prefix, layer_index, name); - header.tensor(reader, &key, device) - }; - Self::load_inner(lt, prefix, n_heads) - } - - #[cfg(target_arch = "wasm32")] - pub fn from_web( - header: &Header, - tensor_map: &mut TensorMap, - layer_index: usize, - n_heads: usize, - prefix: &str, - device: &Device, - ) -> anyhow::Result { - let lt = |name: &str| { - let key = format!("model.{}.layers.{}.{}", prefix, layer_index, name); - let tensor = tensor_map - .remove(&key) - .ok_or_else(|| anyhow::anyhow!("missing tensor"))?; - ratchet_from_gguf_web(tensor, device) - }; - Self::load_inner(lt, prefix, n_heads) - } - - fn load_inner(mut lt: F, prefix: &str, n_heads: usize) -> anyhow::Result - where - F: FnMut(&str) -> anyhow::Result, - { - let attn_ln = LayerNorm::new( - lt("self_attn_layer_norm.weight")?, - Some(lt("self_attn_layer_norm.bias")?), - 1e-5, - ); - //model.encoder.layers.0.self_attn.v_proj.weight - let attn = MultiHeadAttention::new( - Linear::new( - lt("self_attn.q_proj.weight")?, - Some(lt("self_attn.q_proj.bias")?), - ), - Linear::new(lt("self_attn.k_proj.weight")?, None), - Linear::new( - lt("self_attn.v_proj.weight")?, - Some(lt("self_attn.v_proj.bias")?), - ), - Linear::new( - lt("self_attn.out_proj.weight")?, - Some(lt("self_attn.out_proj.bias")?), - ), - n_heads, - ); - - let (x_attn_ln, x_attn) = if prefix == "decoder" { - let x_attn_ln = LayerNorm::new( - lt("encoder_attn_layer_norm.weight")?, - Some(lt("encoder_attn_layer_norm.bias")?), - 1e-5, - ); - let x_attn = MultiHeadAttention::new( - Linear::new( - lt("encoder_attn.q_proj.weight")?, - Some(lt("encoder_attn.q_proj.bias")?), - ), - Linear::new(lt("encoder_attn.k_proj.weight")?, None), - Linear::new( - lt("encoder_attn.v_proj.weight")?, - Some(lt("encoder_attn.v_proj.bias")?), - ), - Linear::new( - lt("encoder_attn.out_proj.weight")?, - Some(lt("encoder_attn.out_proj.bias")?), - ), - n_heads, - ); - (Some(x_attn_ln), Some(x_attn)) - } else { - (None, None) - }; - - let mlp_ln = LayerNorm::new( - lt("final_layer_norm.weight")?, - Some(lt("final_layer_norm.bias")?), - 1e-5, - ); - let mlp = MLP::new( - Linear::new(lt("fc1.weight")?, Some(lt("fc1.bias")?)), - Linear::new(lt("fc2.weight")?, Some(lt("fc2.bias")?)), - ); - Ok(Self { - attn_ln, - attn, - x_attn_ln, - x_attn, - mlp_ln, - mlp, - }) - } -} diff --git a/crates/ratchet-models/src/whisper/samplers/greedy.rs b/crates/ratchet-models/src/whisper/samplers/greedy.rs deleted file mode 100644 index 7635a409..00000000 --- a/crates/ratchet-models/src/whisper/samplers/greedy.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::whisper::task::DecodeError; -use crate::whisper::tokenizer::WhisperTokenizer; - -use ndarray::Axis; -use ndarray_stats::QuantileExt; -use ratchet::Tensor; - -pub struct GreedySampler; - -impl GreedySampler { - pub fn sample( - mut tokens: Vec, - logits: Tensor, - ) -> Result<(Tensor, Vec, bool), DecodeError> { - let nd_logits = logits.to_ndarray_view::(); - let next_tokens = nd_logits - .map_axis(Axis(1), |row| row.argmax_skipnan()) - .iter() - .map(|r| { - r.as_ref() - .map_err(|_| DecodeError::InvalidLogits) - .map(|v| *v as i32) - }) - .collect::, DecodeError>>()?; - - tokens.extend_from_slice(&next_tokens); - let completed = tokens[tokens.len() - 1] == WhisperTokenizer::EOT; - Ok((logits, tokens, completed)) - } -} diff --git a/crates/ratchet-models/src/whisper/samplers/mod.rs b/crates/ratchet-models/src/whisper/samplers/mod.rs deleted file mode 100644 index c6c9bc48..00000000 --- a/crates/ratchet-models/src/whisper/samplers/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod greedy; - -pub use greedy::*; diff --git a/crates/ratchet-models/src/whisper/spectrogram.rs b/crates/ratchet-models/src/whisper/spectrogram.rs deleted file mode 100644 index ad440f74..00000000 --- a/crates/ratchet-models/src/whisper/spectrogram.rs +++ /dev/null @@ -1,166 +0,0 @@ -//Adapted from: https://github.com/tanmayb123/OpenAI-Whisper-CoreML -use ndarray::{Array1, Array2}; -use ndarray_stats::QuantileExt; -use num::complex::Complex; -use ratchet::Tensor; -use realfft::{RealFftPlanner, RealToComplex}; -use std::f32::consts::PI; -use std::sync::Arc; - -pub static SAMPLE_RATE: usize = 16000; -pub static N_FFT: usize = 400; -pub static HOP_LENGTH: usize = 160; -pub static CHUNK_LENGTH: usize = 30; -pub static N_AUDIO_CTX: usize = 1500; //same for all -pub static N_SAMPLES: usize = SAMPLE_RATE * CHUNK_LENGTH; // 480000 -pub static N_FRAMES: usize = N_SAMPLES / HOP_LENGTH; // 3000 -pub static FFT_PAD: usize = N_FFT / 2; - -#[derive(Debug, thiserror::Error)] -pub enum AudioError { - #[error("Audio must be 30 seconds long (with stft padding): {0} != {1}")] - InvalidLength(usize, usize), - #[error("Invalid audio provided: {0}")] - InvalidAudio(#[from] anyhow::Error), -} - -pub struct SpectrogramGenerator { - fft_plan: Arc>, - hann_window: Array1, - mels: Array2, -} - -impl std::fmt::Debug for SpectrogramGenerator { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SpectrogramGenerator").finish() - } -} - -impl SpectrogramGenerator { - pub fn new(mels: Vec) -> Self { - let mut planner = RealFftPlanner::new(); - let n_mels = mels.len() / (N_FFT / 2 + 1); - Self { - fft_plan: planner.plan_fft_forward(N_FFT), - hann_window: Self::hann_window(), - mels: Array2::from_shape_vec((n_mels, N_FFT / 2 + 1), mels).unwrap(), - } - } - - fn hann_window() -> Array1 { - let window = (0..N_FFT) - .map(|i| (i as f32 * 2.0 * PI) / N_FFT as f32) - .map(|i| (1.0 - i.cos()) / 2.0) - .collect::>(); - Array1::from(window) - } - - fn fft(&self, audio: &[f32]) -> Vec> { - let mut input = Array1::from_vec(audio.to_vec()); - input *= &self.hann_window; - let mut spectrum = self.fft_plan.make_output_vec(); - self.fft_plan - .process(input.as_slice_mut().unwrap(), &mut spectrum) - .unwrap(); - spectrum - } - - fn mel_spectrogram(&self, audio: &[f32]) -> Tensor { - let n_frames = (audio.len() - N_FFT) / HOP_LENGTH; - let right_padding = N_SAMPLES + FFT_PAD; //padding is all 0s, so we can ignore it - - let mut spectrogram = Array2::::zeros((201, n_frames)); - for i in (0..audio.len() - right_padding).step_by(HOP_LENGTH) { - if i / HOP_LENGTH >= n_frames { - break; - } - let fft = self.fft(&audio[i..i + N_FFT]); - let spectrogram_col = fft.iter().map(|c| c.norm_sqr()).collect::>(); - spectrogram - .column_mut(i / HOP_LENGTH) - .assign(&spectrogram_col); - } - - let mut mel_spec = self.mels.dot(&spectrogram); - mel_spec.mapv_inplace(|x| x.max(1e-10).log10()); - let max = *mel_spec.max().unwrap(); - mel_spec.mapv_inplace(|x| (x.max(max - 8.0) + 4.0) / 4.0); - let expanded = mel_spec.insert_axis(ndarray::Axis(0)); - Tensor::from(expanded.into_dyn()) - } - - pub fn generate(&self, audio: Vec) -> Result { - if audio.is_empty() { - return Err(AudioError::InvalidAudio(anyhow::anyhow!( - "Audio must be non-empty" - ))); - } - let padded = Self::pad_audio(audio, N_SAMPLES); - Ok(self.mel_spectrogram(&padded)) - } - - //The padding done by OAI is as follows: - //1. First explicitly pad with (CHUNK_LENGTH * SAMPLE_RATE) (480,000) zeros - //2. Then perform a reflection padding of FFT_PAD (200) samples on each side - // This must be done with care, because we have already performed the explicit padding - // the pre-padding will contain non-zero values, but the post-padding must be zero - pub fn pad_audio(audio: Vec, padding: usize) -> Vec { - let padded_len = FFT_PAD + audio.len() + padding + FFT_PAD; - let mut padded_samples = vec![0.0; padded_len]; - - let mut reflect_padding = vec![0.0; FFT_PAD]; - for i in 0..FFT_PAD { - reflect_padding[i] = audio[FFT_PAD - i]; - } - - padded_samples[0..FFT_PAD].copy_from_slice(&reflect_padding); - padded_samples[FFT_PAD..(FFT_PAD + audio.len())].copy_from_slice(&audio); - padded_samples - } -} - -#[cfg(all(test, feature = "pyo3", not(target_arch = "wasm32")))] -mod tests { - use super::SpectrogramGenerator; - use hf_hub::api::sync::Api; - use ratchet::test_util::run_py_prg; - use ratchet::DType; - use std::path::PathBuf; - - const MAX_DIFF: f32 = 5e-5; - - pub fn load_npy(path: PathBuf) -> Vec { - let bytes = std::fs::read(path).unwrap(); - npyz::NpyFile::new(&bytes[..]).unwrap().into_vec().unwrap() - } - - fn load_sample(path: PathBuf) -> Vec { - let mut reader = hound::WavReader::open(path).unwrap(); - reader - .samples::() - .map(|x| x.unwrap() as f32 / 32768.0) - .collect::>() - } - - #[test] - fn spectrogram_matches() { - let api = Api::new().unwrap(); - let repo = api.dataset("FL33TW00D-HF/ratchet-util".to_string()); - let gb0 = repo.get("erwin_jp.wav").unwrap(); - let mels = repo.get("mel_filters_128.npy").unwrap(); - let prg = format!( - r#" -import whisper -import numpy as np -def ground_truth(): - audio = whisper.load_audio("{}") - return whisper.log_mel_spectrogram(audio, n_mels=128, padding=480000).numpy()[np.newaxis] -"#, - gb0.to_str().unwrap() - ); - let ground_truth = run_py_prg(prg.to_string(), &[], &[], DType::F32).unwrap(); - let generator = SpectrogramGenerator::new(load_npy(mels)); - let result = generator.generate(load_sample(gb0)).unwrap(); - ground_truth.all_close(&result, MAX_DIFF, MAX_DIFF).unwrap(); - } -} diff --git a/crates/ratchet-models/src/whisper/task.rs b/crates/ratchet-models/src/whisper/task.rs deleted file mode 100644 index c3d698fe..00000000 --- a/crates/ratchet-models/src/whisper/task.rs +++ /dev/null @@ -1,330 +0,0 @@ -use super::{ - decoder::WhisperDecoder, logit_mutators::*, samplers::*, spectrogram::*, - tokenizer::WhisperTokenizer, transcript::*, -}; -use crate::whisper::options::{DecodingOptions, Prompt}; -use ndarray::{s, Axis}; -use ratchet::{shape, Device, Tensor}; -use ratchet_nn::Module; - -#[derive(Debug, thiserror::Error)] -pub enum DecodeError { - #[error("No valid logits found")] - InvalidLogits, - #[error("Tokenizer error: {0}")] - TokenizerError(#[from] tokenizers::Error), - #[error("Unknown error: {0}")] - UnknownError(#[from] anyhow::Error), - #[error("Failed to resolve tensor: {0}")] - TensorResolveError(#[from] ratchet::TensorError), -} - -pub struct DecodingTask { - tokenizer: WhisperTokenizer, - options: DecodingOptions, - sample_len: u32, - logit_mutators: Vec>, - initial_tokens: Option>, - initial_tokens_len: Option, -} - -impl DecodingTask { - fn get_initial_tokens(&self) -> Vec { - let mut init_tokens = self.tokenizer.sot_sequence(); - if let Some(prompt) = &self.options.prompt { - let prompt_tokens = match prompt { - Prompt::Tokens(tokens) => tokens.clone(), - Prompt::Text(text) => self - .tokenizer - .encode(format!(" {}", text).as_str(), false) - .unwrap(), - }; - let max_prompt_length = 448 / 2 - 1; // equivalent to self.n_ctx // 2 - 1 in python - let prompt_length = prompt_tokens.len().min(max_prompt_length); - let mut tokens = vec![self.tokenizer.sot_prev()]; - tokens.extend_from_slice(&prompt_tokens[prompt_tokens.len() - prompt_length..]); - tokens.extend(init_tokens); - init_tokens = tokens; - } - init_tokens - } - - pub fn new(options: DecodingOptions, tokenizer: WhisperTokenizer) -> Self { - let sample_len = options.sample_len.unwrap_or(256); - let _selected_lang = options.language.as_ref().unwrap(); - let max_initial_timestamp = options.max_initial_timestamp; - let mut task = DecodingTask { - tokenizer, - options, - logit_mutators: vec![], - sample_len, - initial_tokens: None, - initial_tokens_len: None, - }; - task.initial_tokens = Some(task.get_initial_tokens()); - task.initial_tokens_len = Some(task.initial_tokens.as_ref().unwrap().len()); - - let mut max_initial_timestamp_index = None; - if let Some(max_initial_timestamp) = max_initial_timestamp { - let precision = CHUNK_LENGTH as f32 / N_AUDIO_CTX as f32; - max_initial_timestamp_index = - Some((max_initial_timestamp / precision).round() as usize); - } - task.logit_mutators.push(Box::new(ApplyTimestampRules { - sample_begin: task.initial_tokens_len.unwrap(), - max_initial_timestamp_index, - })); - - task - } - - #[cfg(not(target_arch = "wasm32"))] - fn main_loop( - &self, - decoder: &mut WhisperDecoder, - audio_ctx: Tensor, - callback: &Option, - ) -> Result, DecodeError> { - use ratchet::DType; - - let mut tokens = self.get_initial_tokens(); - let sliced_vocab_size = self.tokenizer.vocab_size(); - let device = audio_ctx.device().clone(); - let mut timestamps_seen = 0; - - for _ in 0..self.sample_len { - let input = if tokens.len() > self.initial_tokens_len.unwrap() { - &tokens[tokens.len() - 1..] - } else { - &tokens - }; - let input_t = Tensor::from_data(input, shape![1, input.len()], device.clone()); - - let logits = decoder - .schedule([audio_ctx.clone(), input_t])? - .cast(DType::F32)? - .resolve()?; - decoder.cache_mut().update(input.len()); - - let cpu_logits = logits.to(&Device::CPU)?; - let mut logits = Self::slice_logits(cpu_logits, sliced_vocab_size); - let token_t = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], Device::CPU); - for m in &self.logit_mutators { - logits = m.apply(logits, &self.tokenizer, Some(&token_t))?; - } - - let (_, new_tokens, completed) = GreedySampler::sample(tokens, logits)?; - - if let Some(ref cb) = callback { - self.handle_callback(&self.tokenizer, &new_tokens, &mut timestamps_seen, cb); - } - - tokens = new_tokens; - if completed { - break; - } - } - Ok(tokens) - } - - #[cfg(target_arch = "wasm32")] - async fn main_loop( - &self, - decoder: &mut WhisperDecoder, - audio_ctx: Tensor, - callback: &Option, - ) -> Result, DecodeError> { - let mut tokens = self.get_initial_tokens(); - let device = audio_ctx.device().clone(); - let sliced_vocab_size = self.tokenizer.vocab_size(); - let mut timestamps_seen = 0; - - for _ in 0..self.sample_len { - let input = if tokens.len() > self.initial_tokens_len.unwrap() { - &tokens[tokens.len() - 1..] - } else { - &tokens - }; - let input_t = Tensor::from_data(input, shape![1, input.len()], device.clone()); - - let logits = decoder.schedule([audio_ctx.clone(), input_t])?.resolve()?; - decoder.cache_mut().update(input.len()); - - let cpu_logits = logits.to(&Device::CPU).await?; - let mut logits = Self::slice_logits(cpu_logits, sliced_vocab_size); - let token_t = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], Device::CPU); - for m in &self.logit_mutators { - logits = m.apply(logits, &self.tokenizer, Some(&token_t))?; - } - - let (_, new_tokens, completed) = GreedySampler::sample(tokens, logits)?; - - if let Some(ref cb) = callback { - self.handle_callback(&self.tokenizer, &new_tokens, &mut timestamps_seen, cb); - } - - tokens = new_tokens; - if completed { - break; - } - } - Ok(tokens) - } - - fn handle_callback( - &self, - tokenizer: &WhisperTokenizer, - new_tokens: &[i32], - timestamps_seen: &mut i32, - callback: impl Fn(StreamedSegment), - ) { - if tokenizer.is_timestamp(new_tokens[new_tokens.len() - 1]) { - *timestamps_seen += 1; - if *timestamps_seen % 2 == 0 { - let previous_timestamp = new_tokens[..new_tokens.len() - 2] - .iter() - .rposition(|x| tokenizer.is_timestamp(*x)); - if let Some(previous_timestamp) = previous_timestamp { - callback(StreamedSegment::from_tokens( - tokenizer, - &new_tokens[previous_timestamp..], - self.options.time_offset.unwrap_or(0.0), - false, - )); - } - } - } - } - - /// Slice logits from [1xnum_tokensx51872] -> [1x1x51865] - pub(crate) fn slice_logits(logits: Tensor, vocab_size: usize) -> Tensor { - let nd_logits = logits.into_ndarray::(); - let sliced = nd_logits - .slice(s![.., -1.., ..vocab_size]) - .remove_axis(Axis(1)); - Tensor::from(sliced.to_owned().into_dyn()) - } - - pub fn build_segments( - tokenizer: &WhisperTokenizer, - tokens: Vec, - offset: f64, - segment_size: usize, - segment_duration: usize, - input_stride: usize, - ) -> (Vec, usize) { - let content_tokens = tokens; - let content_length = content_tokens.len(); - if content_length < 2 { - log::error!("Failed to build segments."); - return (Vec::new(), 0); - } - let (penultimate, last) = ( - content_tokens[content_length - 2], - content_tokens[content_length - 1], - ); - - let single_timestamp_ending = - !tokenizer.is_timestamp(penultimate) && tokenizer.is_timestamp(last); - - let mut consecutive = content_tokens - .windows(2) - .enumerate() - .filter_map(|(i, x)| { - if tokenizer.is_timestamp(x[0]) && tokenizer.is_timestamp(x[1]) { - Some(i + 1) - } else { - None - } - }) - .collect::>(); - - let advance; - let segments; - if !consecutive.is_empty() { - // if the output contains two consecutive timestamp tokens - if single_timestamp_ending { - consecutive.push(content_length); - } - - #[allow(unused_assignments)] - let mut last_slice = 0; - (segments, last_slice) = - consecutive - .iter() - .fold((Vec::new(), 0), |(mut acc, last_slice), &slice| { - let segment_tokens = &content_tokens[last_slice..slice]; - acc.push(Segment::from_tokens( - tokenizer, - segment_tokens, - offset, - false, - )); - (acc, slice) - }); - - advance = if single_timestamp_ending { - segment_size - } else { - let last_timestamp_pos = - content_tokens[last_slice - 1] - tokenizer.timestamp_begin(); - last_timestamp_pos as usize * input_stride - } - } else { - let duration = content_tokens - .iter() - .filter(|&x| tokenizer.is_timestamp(*x)) - .last() - .map_or(segment_duration as f64, |&last_ts| { - let last_timestamp_pos = last_ts - tokenizer.timestamp_begin(); - last_timestamp_pos as f64 * input_stride as f64 * (HOP_LENGTH as f64) - / (SAMPLE_RATE as f64) - }); - - let segment_tokens = content_tokens.iter().map(|x| *x as u32).collect::>(); - segments = vec![Segment::new( - offset, - offset + duration, - segment_tokens, - false, - )]; - advance = segment_size; - } - - (segments, advance) - } - - #[cfg(target_arch = "wasm32")] - pub async fn run( - &self, - decoder: &mut WhisperDecoder, - audio_ctx: Tensor, - callback: &Option, - ) -> Result, DecodeError> { - let mut tokens = self.main_loop(decoder, audio_ctx, &callback).await?; - - tokens = tokens.drain(self.initial_tokens_len.unwrap()..).collect(); - let eot_index = tokens.iter().position(|x| *x == WhisperTokenizer::EOT); - if let Some(eot_index) = eot_index { - tokens.truncate(eot_index); - } - Ok(tokens) - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn run( - &self, - decoder: &mut WhisperDecoder, - audio_ctx: Tensor, - callback: &Option, - ) -> Result, DecodeError> { - let mut tokens = self.main_loop(decoder, audio_ctx, callback)?; - - tokens = tokens.drain(self.initial_tokens_len.unwrap()..).collect(); - let eot_index = tokens.iter().position(|x| *x == WhisperTokenizer::EOT); - if let Some(eot_index) = eot_index { - tokens.truncate(eot_index); - } - Ok(tokens) - } -} diff --git a/crates/ratchet-models/src/whisper/tokenizer.rs b/crates/ratchet-models/src/whisper/tokenizer.rs deleted file mode 100644 index af008bdc..00000000 --- a/crates/ratchet-models/src/whisper/tokenizer.rs +++ /dev/null @@ -1,201 +0,0 @@ -use crate::whisper::options::{Language, Task}; -use tokenizers::Tokenizer; - -#[cfg(not(target_arch = "wasm32"))] -use hf_hub::api::sync::Api; -#[cfg(target_arch = "wasm32")] -use {ratchet_hub::ApiBuilder, ratchet_hub::RepoType, wasm_bindgen::JsError}; - -lazy_static::lazy_static! { - pub static ref LANGUAGES: [&'static str; 100] = { - [ - "en", "zh", "de", "es", "ru", "ko", "fr", "ja", "pt", "tr", "pl", "ca", "nl", "ar", - "sv", "it", "id", "hi", "fi", "vi", "he", "uk", "el", "ms", "cs", "ro", "da", "hu", - "ta", "no", "th", "ur", "hr", "bg", "lt", "la", "mi", "ml", "cy", "sk", "te", "fa", - "lv", "bn", "sr", "az", "sl", "kn", "et", "mk", "br", "eu", "is", "hy", "ne", "mn", - "bs", "kk", "sq", "sw", "gl", "mr", "pa", "si", "km", "sn", "yo", "so", "af", "oc", - "ka", "be", "tg", "sd", "gu", "am", "yi", "lo", "uz", "fo", "ht", "ps", "tk", "nn", - "mt", "sa", "lb", "my", "bo", "tl", "mg", "as", "tt", "haw", "ln", "ha", "ba", "jw", - "su", "yue", - ] - }; -} - -//Wrapper around tokenizers::Tokenizer with helpers -#[derive(Clone)] -pub struct WhisperTokenizer { - inner: Tokenizer, - language: i32, - task: Task, -} - -impl WhisperTokenizer { - pub const SOT: i32 = 50258; - pub const EOT: i32 = 50257; - pub const LANGUAGES_BEGIN: usize = 50259; - pub const BLANK: i32 = 220; - - //https://github.com/openai/whisper/blob/1cea4357687b676b293cb5473e1ade25f5b1cef7/whisper/tokenizer.py#L242 - pub const NON_SPEECH: [i32; 82] = [ - 1, 2, 7, 8, 9, 10, 14, 25, 26, 27, 28, 29, 31, 58, 59, 60, 61, 62, 63, 90, 91, 92, 93, 359, - 503, 522, 542, 873, 893, 902, 918, 922, 931, 1350, 1853, 1982, 2460, 2627, 3246, 3253, - 3268, 3536, 3846, 3961, 4183, 4667, 6585, 6647, 7273, 9061, 9383, 10428, 10929, 11938, - 12033, 12331, 12562, 13793, 14157, 14635, 15265, 15618, 16553, 16604, 18362, 18956, 20075, - 21675, 22520, 26130, 26161, 26435, 28279, 29464, 31650, 32302, 32470, 36865, 42863, 47425, - 49870, 50254, - ]; - - #[cfg(not(target_arch = "wasm32"))] - pub fn load_inner(bytes: Option>, v3: bool) -> Tokenizer { - if let Some(bytes) = bytes { - Tokenizer::from_bytes(bytes).unwrap() - } else { - Self::fetch(v3) - } - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn load(bytes: Option>, v3: bool, language: Language, task: Task) -> Self { - let inner = Self::load_inner(bytes, v3); - let mut tokenizer = Self { - inner, - language: -1, - task, - }; - tokenizer.set_language(language); - tokenizer - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn fetch(v3: bool) -> Tokenizer { - let api = Api::new().unwrap(); - - //TODO: dumb hack - let repo_name = match v3 { - true => "openai/whisper-large-v3", - false => "openai/whisper-tiny", - }; - - let tokenizer_repo = api.model(repo_name.to_string()); - let tokenizer_path = tokenizer_repo.get("tokenizer.json").unwrap(); - Tokenizer::from_file(tokenizer_path).unwrap() - } - - #[cfg(target_arch = "wasm32")] - pub async fn load_inner(bytes: Option>, v3: bool) -> Tokenizer { - use wasm_bindgen::JsValue; - - if let Some(bytes) = bytes { - Tokenizer::from_bytes(bytes).unwrap() - } else { - Self::fetch(v3).await.map_err(JsValue::from).unwrap() - } - } - - #[cfg(target_arch = "wasm32")] - pub async fn load(bytes: Option>, v3: bool, language: Language, task: Task) -> Self { - let inner = Self::load_inner(bytes, v3).await; - let mut tokenizer = Self { - inner, - language: -1, - task, - }; - tokenizer.set_language(language); - tokenizer - } - - #[cfg(target_arch = "wasm32")] - pub async fn fetch(v3: bool) -> Result { - let repo_name = match v3 { - true => "openai/whisper-large-v3", - false => "openai/whisper-tiny", - }; - - let model_repo = ApiBuilder::from_hf(repo_name, RepoType::Model).build(); - let model_bytes = model_repo.get("tokenizer.json").await?; - Ok(Tokenizer::from_bytes(model_bytes.to_vec()).unwrap()) - } - - pub fn set_language(&mut self, language: Language) { - let token = match language { - Language::String(s) => { - let lang_position = LANGUAGES.iter().position(|x| *x == s); - if lang_position.is_none() { - panic!("Language {} not found", s); - } - - WhisperTokenizer::SOT + 1 + lang_position.unwrap() as i32 - } - Language::Token(t) => t, - }; - self.language = token; - } - - #[inline] - pub fn sot_prev(&self) -> i32 { - self.inner - .encode("<|startofprev|>", false) - .unwrap() - .get_ids()[0] as i32 - } - - #[inline] - pub fn sot_sequence(&self) -> Vec { - vec![Self::SOT, self.language, self.task.as_token(self)] - } - - #[inline] - pub fn transcribe(&self) -> i32 { - self.inner - .encode("<|transcribe|>", false) - .unwrap() - .get_ids()[0] as i32 - } - - #[inline] - pub fn translate(&self) -> i32 { - self.inner.encode("<|translate|>", false).unwrap().get_ids()[0] as i32 - } - - #[inline] - pub fn notimestamps(&self) -> i32 { - self.inner - .encode("<|notimestamps|>", false) - .unwrap() - .get_ids()[0] as i32 - } - - #[inline] - pub fn timestamp_begin(&self) -> i32 { - self.inner.encode("<|0.00|>", false).unwrap().get_ids()[0] as i32 - } - - #[inline] - pub fn is_timestamp(&self, token: i32) -> bool { - (self.timestamp_begin()..=self.vocab_size() as i32).contains(&token) - } - - #[inline] - pub fn is_multilingual(&self) -> bool { - self.inner.get_vocab_size(true) >= 51865 - } - - #[inline] - pub fn vocab_size(&self) -> usize { - self.inner.get_vocab_size(true) - } - - pub fn encode(&self, text: &str, skip_special: bool) -> Result, tokenizers::Error> { - Ok(self - .inner - .encode(text, skip_special)? - .get_ids() - .iter() - .map(|x| *x as _) - .collect()) - } - - pub fn decode(&self, tokens: &[u32], skip_special: bool) -> Result { - self.inner.decode(tokens, skip_special) - } -} diff --git a/crates/ratchet-models/src/whisper/transcribe.rs b/crates/ratchet-models/src/whisper/transcribe.rs deleted file mode 100644 index 7e3ecf86..00000000 --- a/crates/ratchet-models/src/whisper/transcribe.rs +++ /dev/null @@ -1,174 +0,0 @@ -use crate::whisper::model::Whisper; -use crate::whisper::options::*; -use crate::whisper::{spectrogram::*, task::*, tokenizer::*, transcript::*}; -use ratchet_nn::Module; -use std::cmp::min; -use web_time::Instant; - -#[cfg(not(target_arch = "wasm32"))] -pub fn transcribe( - model: &mut Whisper, - audio: Vec, - mut decode_options: DecodingOptions, - callback: Option, -) -> anyhow::Result { - let n_mels = model.config.n_mels; - let runtime = Instant::now(); - let mel = model.specgen.generate(audio)?.to(&model.device)?; - let content_frames = mel.shape()[mel.rank() - 1] - N_FRAMES; - - if decode_options.language.is_none() { - if !model.is_multilingual() { - log::warn!("No language specified, using English"); - decode_options.language = Some(Language::String("en".to_string())); - } else { - log::warn!("No language specified, using language detection"); - let mel = mel.clone().slice(&[0..1, 0..n_mels, 0..3000])?; - decode_options.language = Some(model.detect_language(mel)?); - } - } - - let language = decode_options.language.as_ref().unwrap(); - let task = decode_options.task; - let tokenizer = WhisperTokenizer::load(None, n_mels == 128, language.clone(), task); - - let mut seek = 0; - let input_stride = N_FRAMES / N_AUDIO_CTX; - let mut all_tokens = Vec::with_capacity(512); - let mut all_segments = Vec::with_capacity(512); - let prompt_since_reset = 0; - - while seek < content_frames { - let mut decode_options = decode_options.clone(); - let time_offset = (seek * HOP_LENGTH) as f64 / SAMPLE_RATE as f64; - decode_options.time_offset = Some(time_offset); - let mel_segment = mel - .clone() - .slice(&[0..1, 0..n_mels, seek..(seek + N_FRAMES)])?; - log::info!("Processing segment: {} -> {}", seek, seek + N_FRAMES); - - let segment_size = min(N_FRAMES, content_frames - seek); - let segment_duration = segment_size * HOP_LENGTH / SAMPLE_RATE; - - if !all_tokens.is_empty() { - decode_options.prompt = Some(Prompt::Tokens(all_tokens[prompt_since_reset..].to_vec())); - } - - let hs = model.encoder.schedule(mel_segment)?.resolve()?; - - let task = DecodingTask::new(decode_options, tokenizer.clone()); - let decoded = task.run(&mut model.decoder, hs, &callback)?; - let (segments, advance) = DecodingTask::build_segments( - &tokenizer, - decoded, - time_offset, - segment_size, - segment_duration, - input_stride, - ); - let all_segment_tokens = segments - .iter() - .flat_map(|s| s.tokens.iter().copied()) - .map(|x| x as i32) - .collect::>(); - all_tokens.extend(all_segment_tokens); - all_segments.extend(segments); - model.decoder.reset(); - seek += advance; - } - - let mut t = TranscriptionResult::new(runtime.elapsed(), all_segments, None); - t.generate_formatted(&tokenizer); - Ok(t) -} - -#[cfg(target_arch = "wasm32")] -pub async fn transcribe( - model: &mut Whisper, - audio: Vec, - mut decode_options: DecodingOptions, - callback: Option, -) -> anyhow::Result { - let n_mels = model.config.n_mels as usize; - let runtime = Instant::now(); - let mel = model.specgen.generate(audio)?.to(&model.device).await?; - let content_frames = mel.shape()[mel.rank() - 1] - N_FRAMES; - - if decode_options.language.is_none() { - if !model.is_multilingual() { - log::warn!("No language specified, using English"); - decode_options.language = Some(Language::String("en".to_string())); - } else { - log::warn!("No language specified, using language detection"); - let mel = mel.clone().slice(&[0..1, 0..n_mels, 0..3000])?; - decode_options.language = Some(model.detect_language(mel).await?); - } - } - - let language = decode_options.language.as_ref().unwrap(); - let task = decode_options.task; - let tokenizer = - WhisperTokenizer::load(None, n_mels == 128, language.clone(), task.clone()).await; - - let mut seek = 0; - let input_stride = N_FRAMES / N_AUDIO_CTX; - let mut all_tokens = Vec::with_capacity(512); - let mut all_segments = Vec::with_capacity(512); - let prompt_since_reset = 0; - - while seek < content_frames { - let mut decode_options = decode_options.clone(); - let time_offset = (seek * HOP_LENGTH) as f64 / SAMPLE_RATE as f64; - decode_options.time_offset = Some(time_offset); - let mel_segment = mel - .clone() - .slice(&[0..1, 0..n_mels, seek..(seek + N_FRAMES)])?; - log::info!("Processing segment: {} -> {}", seek, seek + N_FRAMES); - - let segment_size = min(N_FRAMES, content_frames - seek); - let segment_duration = segment_size * HOP_LENGTH / SAMPLE_RATE; - - if !all_tokens.is_empty() { - decode_options.prompt = Some(Prompt::Tokens(all_tokens[prompt_since_reset..].to_vec())); - } - - let hs = model.encoder.schedule(mel_segment)?.resolve()?; - - let dbg = hs.clone().to(&ratchet::Device::CPU).await; - log::warn!("HS: {:?}", dbg); - - let task = DecodingTask::new(decode_options, tokenizer.clone()); - let decoded = task.run(&mut model.decoder, hs, &callback).await?; - - let (segments, advance) = DecodingTask::build_segments( - &tokenizer, - decoded, - time_offset, - segment_size, - segment_duration, - input_stride, - ); - let all_segment_tokens = segments - .iter() - .flat_map(|s| s.tokens.iter().copied()) - .map(|x| x as i32) - .collect::>(); - all_tokens.extend(all_segment_tokens); - all_segments.extend(segments); - model.decoder.reset(); - seek += advance; - } - - if let Some(cb) = callback { - cb(StreamedSegment::from_tokens( - &tokenizer, - &[WhisperTokenizer::EOT], - content_frames as f64 / 100., - true, - )); - } - - let mut t = TranscriptionResult::new(runtime.elapsed(), all_segments, None); - t.generate_formatted(&tokenizer); - Ok(t) -} diff --git a/crates/ratchet-models/src/whisper/transcript.rs b/crates/ratchet-models/src/whisper/transcript.rs deleted file mode 100644 index 0fd1df84..00000000 --- a/crates/ratchet-models/src/whisper/transcript.rs +++ /dev/null @@ -1,159 +0,0 @@ -use super::spectrogram::*; -use super::tokenizer::WhisperTokenizer; -use num::integer::div_floor; -use serde::{Deserialize, Serialize}; -use std::time::Duration; - -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - -#[cfg_attr(target_arch = "wasm32", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, derive_new::new)] -pub struct TranscriptionResult { - pub processing_time: Duration, - pub segments: Vec, - pub formatted: Option, -} - -impl TranscriptionResult { - pub fn generate_formatted(&mut self, tokenizer: &WhisperTokenizer) { - let formatted = self.as_oai(tokenizer); - self.formatted = Some(formatted); - } - - fn format_single(&self, segment: &Segment, tokenizer: &WhisperTokenizer) -> String { - let fragment_tokens = segment - .tokens - .iter() - .copied() - .filter(|x| *x < WhisperTokenizer::EOT as _) - .collect::>(); - let fragment_text = tokenizer.decode(fragment_tokens.as_slice(), true).unwrap(); - format!( - "[{} --> {}] {}\n", - Self::format_timestamp(segment.start, false, "."), - Self::format_timestamp(segment.stop, false, "."), - fragment_text.trim().replace("-->", "->") - ) - } - - pub fn as_oai(&self, tokenizer: &WhisperTokenizer) -> String { - self.segments - .iter() - .map(|segment| self.format_single(segment, tokenizer)) - .collect::() - } - - fn format_timestamp(num: f64, always_include_hours: bool, decimal_marker: &str) -> String { - assert!(num >= 0.0, "non-negative timestamp expected"); - let milliseconds: i64 = (num * 1000.0) as i64; - - let hours = div_floor(milliseconds, 3_600_000); - let minutes = div_floor(milliseconds % 3_600_000, 60_000); - let seconds = div_floor(milliseconds % 60_000, 1000); - let milliseconds = milliseconds % 1000; - - let hours_marker = if always_include_hours || hours != 0 { - format!("{:02}:", hours) - } else { - String::new() - }; - - format!( - "{}{:02}:{:02}{}{:03}", - hours_marker, minutes, seconds, decimal_marker, milliseconds - ) - } -} - -#[derive(Debug, Serialize, Deserialize, derive_new::new)] -pub struct Segment { - pub start: f64, - pub stop: f64, - pub tokens: Vec, - pub last: bool, -} - -impl Segment { - pub fn from_tokens( - tokenizer: &WhisperTokenizer, - sliced_tokens: &[i32], - offset: f64, - last: bool, - ) -> Self { - let input_stride = N_FRAMES / N_AUDIO_CTX; // mel frames per output token: 2 - let time_precision: f64 = input_stride as f64 * (HOP_LENGTH as f64) / (SAMPLE_RATE as f64); // time per output token: 0.02 (seconds) - - let start_timestamp_pos = sliced_tokens[0] - tokenizer.timestamp_begin(); - let end_timestamp_pos = - sliced_tokens[sliced_tokens.len() - 1] - tokenizer.timestamp_begin(); - - let segment_tokens = sliced_tokens.iter().map(|x| *x as u32).collect::>(); - - let st = offset + (start_timestamp_pos as f64 * time_precision); - let et = offset + (end_timestamp_pos as f64 * time_precision); - let st = (st * 100.).round() / 100.; - let et = (et * 100.).round() / 100.; - Segment::new(st, et, segment_tokens, last) - } -} - -#[cfg_attr( - target_arch = "wasm32", - wasm_bindgen(getter_with_clone, js_name = Segment), - derive(serde::Serialize, serde::Deserialize) -)] -#[derive(Debug, derive_new::new)] -pub struct StreamedSegment { - pub start: f64, - pub stop: f64, - pub text: String, - pub last: bool, -} - -impl std::fmt::Display for StreamedSegment { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "[{} --> {}] {}", - TranscriptionResult::format_timestamp(self.start, false, "."), - TranscriptionResult::format_timestamp(self.stop, false, "."), - self.text.trim().replace("-->", "->") - ) - } -} - -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -impl StreamedSegment { - pub fn start(&self) -> f64 { - self.start - } - - pub fn stop(&self) -> f64 { - self.stop - } - - pub fn text(&self) -> String { - self.text.clone() - } - - pub fn last(&self) -> bool { - self.last - } - - pub(crate) fn from_tokens( - tokenizer: &WhisperTokenizer, - sliced_tokens: &[i32], - offset: f64, - last: bool, - ) -> Self { - let segment = Segment::from_tokens(tokenizer, sliced_tokens, offset, last); - let segment_tokens = segment - .tokens - .into_iter() - .filter(|t| *t < tokenizer.timestamp_begin() as _) - .collect::>(); - let segment_text = tokenizer.decode(segment_tokens.as_slice(), true).unwrap(); - StreamedSegment::new(segment.start, segment.stop, segment_text, last) - } -} diff --git a/crates/ratchet-models/tests/whisper.rs b/crates/ratchet-models/tests/whisper.rs deleted file mode 100644 index f34ced21..00000000 --- a/crates/ratchet-models/tests/whisper.rs +++ /dev/null @@ -1,218 +0,0 @@ -#![cfg(target_arch = "wasm32")] -wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); - -use ndarray::{s, Axis}; -use ndarray_stats::QuantileExt; -use ratchet::{shape, Device, DeviceRequest, Tensor}; -use ratchet_hub::{ApiBuilder, RepoType}; -use ratchet_loader::gguf::gguf; -use ratchet_models::whisper::{Config, Whisper, WhisperDecoder, WhisperEncoder}; -use ratchet_nn::Module; -use std::path::PathBuf; -use wasm_bindgen::prelude::*; -use wasm_bindgen_test::*; - -fn log_init() { - console_error_panic_hook::set_once(); - log::set_max_level(log::LevelFilter::Off); - console_log::init_with_level(log::Level::Debug).unwrap(); -} - -/* -#[wasm_bindgen_test] -async fn distil_large_v3_encoder() -> Result<(), JsValue> { - log_init(); - let model_repo = - ApiBuilder::from_hf("FL33TW00D-HF/distil-whisper-large-v3", RepoType::Model).build(); - let model_data = model_repo.get("distil-large-v3_q8_0.gguf").await?; - let config_data = model_repo.get("config.json").await?; - - let ground_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let input_npy = ground_repo.get("distil_large_v3_q80_mm0_input.npy").await?; - let ground_npy = ground_repo.get("distil_large_v3_q80_mm0_hs.npy").await?; - - let mut reader = std::io::BufReader::new(std::io::Cursor::new(model_data.to_vec())); - let header = gguf::Header::read(&mut reader).unwrap(); - let config: Config = serde_json::from_slice(&config_data.to_vec()).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).await.unwrap(); - - let input_data = &input_npy.to_vec(); - let input = Tensor::from_npy_bytes::(input_data, &device).unwrap(); - let ground = Tensor::from_npy_bytes::(&ground_npy.to_vec(), &Device::CPU).unwrap(); - - let encoder = WhisperEncoder::load(&header, &config, &mut reader, &device).unwrap(); - let result = encoder - .schedule(input) - .unwrap() - .full() - .unwrap() - .resolve() - .unwrap(); - let ours = result.to(&Device::CPU).await.unwrap(); - ground.all_close(&ours, 1e-3, 1e-3).unwrap(); - Ok(()) -}*/ - -/* -#[wasm_bindgen_test] -async fn distil_large_v3_decoder() -> Result<(), JsValue> { - log_init(); - let model_repo = - ApiBuilder::from_hf("FL33TW00D-HF/distil-whisper-large-v3", RepoType::Model).build(); - let model_data = model_repo.get("distil-large-v3_q8_0.gguf").await?; - let config_data = model_repo.get("config.json").await?; - - let ground_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let hs_data = ground_repo.get("distil_large_v3_q80_mm0_hs.npy").await?; - - let mut reader = std::io::BufReader::new(std::io::Cursor::new(model_data.to_vec())); - let header = gguf::Header::read(&mut reader).unwrap(); - let config: Config = serde_json::from_slice(&config_data.to_vec()).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).await.unwrap(); - let audio_ctx = Tensor::from_npy_bytes::(&hs_data.to_vec(), &device) - .unwrap() - .half() - .unwrap() - .resolve() - .unwrap(); - log::debug!("Audio Context: {:?}", audio_ctx); - let mut decoder = WhisperDecoder::load(&header, &config, &mut reader, &device).unwrap(); - - let mut tokens = vec![50258, 50259, 50360]; - let mut all_tokens = tokens.clone(); - let mut all_logits = vec![]; - while tokens[tokens.len() - 1] != 50257 { - let token_t = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let result = decoder - .schedule([audio_ctx.clone(), token_t]) - .unwrap() - .resolve_debug() - .unwrap(); - - let our_logits = result.to(&Device::CPU).await.unwrap(); - all_logits.push(our_logits.clone()); - let nd_logits = our_logits.to_ndarray_view::(); - log::info!("Logits: {:?}", nd_logits); - - let sliced = nd_logits.slice(s![.., -1.., ..51866]).remove_axis(Axis(1)); - decoder.cache_mut().update(tokens.len()); - - tokens = sliced - .map_axis(Axis(1), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - println!("Token: {:?}", tokens); - panic!(); - all_tokens.extend(tokens.clone()); - } - - let ground_tokens = vec![ - 50258, 50259, 50360, 50365, 639, 307, 264, 4532, 3479, 587, 11, 15578, 264, 881, 2062, 847, - 11, 34674, 5932, 30340, 295, 3123, 4397, 608, 1652, 13, 50517, 50530, 6947, 472, 575, - 12023, 4365, 11, 20899, 11, 10445, 11, 18356, 11, 4225, 4782, 11, 50624, 50626, 1804, 4651, - 3123, 4397, 34922, 8963, 862, 6352, 13, 50695, 50701, 821, 311, 257, 3804, 5214, 11, 2610, - 5214, 11, 6383, 11, 2643, 5214, 11, 293, 544, 13, 50797, 50807, 10246, 8963, 2436, 2965, - 281, 747, 604, 1081, 13, 50875, 50881, 400, 456, 366, 867, 34674, 862, 365, 11, 293, 1184, - 472, 1487, 365, 1080, 1065, 2121, 11377, 11, 51002, 51007, 4532, 3479, 5864, 293, 1019, 11, - 5456, 4122, 300, 30686, 25038, 1286, 13, 51120, 51135, 30062, 264, 6582, 29814, 412, 264, - 10155, 11, 1849, 1426, 11, 587, 11, 264, 3874, 34544, 412, 264, 7267, 3096, 13, 51243, - 51246, 18463, 428, 1032, 412, 264, 1032, 5675, 13, 51287, 51290, 30062, 264, 16629, 7283, - 13, 51320, 51328, 400, 613, 862, 6352, 3318, 1214, 281, 1254, 257, 3123, 4397, 34922, 8963, - 1081, 6352, 11, 370, 27985, 11, 51504, 51504, 370, 6239, 11, 370, 44078, 1688, 356, 9942, - 11, 291, 603, 528, 281, 8963, 552, 439, 13, 51623, 51635, 25642, 12089, 1652, 366, 1027, - 14759, 490, 7336, 836, 65, 13, 51743, 51743, 440, 4356, 436, 366, 11, 264, 1101, 436, 366, - 13, 51834, - ]; - assert_eq!(all_tokens, ground_tokens); - Ok(()) -}*/ - -/* -#[wasm_bindgen_test] -async fn tiny_encoder() -> Result<(), JsValue> { - log_init(); - let model_repo = ApiBuilder::from_hf("FL33TW00D-HF/whisper-tiny", RepoType::Model).build(); - let model_data = model_repo.get("tiny_f32.gguf").await?; - let config_data = model_repo.get("config.json").await?; - - let ground_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let input_npy = ground_repo.get("jfk_tiny_encoder_input.npy").await?; - let ground_npy = ground_repo.get("jfk_tiny_encoder_hs.npy").await?; - - let mut reader = std::io::BufReader::new(std::io::Cursor::new(model_data.to_vec())); - let header = gguf::Header::read(&mut reader).unwrap(); - let config: Config = serde_json::from_slice(&config_data.to_vec()).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).await.unwrap(); - - let input_data = &input_npy.to_vec(); - let input = Tensor::from_npy_bytes::(input_data, &device).unwrap(); - let ground = Tensor::from_npy_bytes::(&ground_npy.to_vec(), &Device::CPU).unwrap(); - - let encoder = WhisperEncoder::load(&header, &config, &mut reader, &device).unwrap(); - let result = encoder.schedule(input).unwrap().resolve().unwrap(); - let ours = result.to(&Device::CPU).await.unwrap(); - ground.all_close(&ours, 1e-3, 1e-3).unwrap(); - Ok(()) -} -*/ - -#[wasm_bindgen_test] -async fn tiny_decoder() -> Result<(), JsValue> { - log_init(); - let model_repo = ApiBuilder::from_hf("FL33TW00D-HF/whisper-tiny", RepoType::Model).build(); - let model_data = model_repo.get("tiny_f32.gguf").await?; - let config_data = model_repo.get("config.json").await?; - - let ground_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let hs_data = ground_repo.get("jfk_tiny_encoder_hs.npy").await?; - - let mut reader = std::io::BufReader::new(std::io::Cursor::new(model_data.to_vec())); - let header = gguf::Header::read(&mut reader).unwrap(); - let config: Config = serde_json::from_slice(&config_data.to_vec()).unwrap(); - - let device = Device::request_device(DeviceRequest::GPU).await.unwrap(); - - let audio_ctx = Tensor::from_npy_bytes::(&hs_data.to_vec(), &device).unwrap(); - let mut decoder = WhisperDecoder::load(&header, &config, &mut reader, &device).unwrap(); - - let mut tokens = vec![50258, 50259, 50359]; - let mut all_tokens = tokens.clone(); - let mut all_logits = vec![]; - let vocab_size = 51865; - while tokens[tokens.len() - 1] != 50257 { - let token_t = Tensor::from_data(tokens.clone(), shape![1, tokens.len()], device.clone()); - let result = decoder - .schedule([audio_ctx.clone(), token_t]) - .unwrap() - .resolve() - .unwrap(); - - let our_logits = result.to(&Device::CPU).await.unwrap(); - all_logits.push(our_logits.clone()); - let nd_logits = our_logits.to_ndarray_view::(); - log::debug!("ND LOGITS: {:?}", nd_logits); - let sliced = nd_logits - .slice(s![.., -1.., ..vocab_size]) - .remove_axis(Axis(1)); - decoder.cache_mut().update(tokens.len()); - - tokens = sliced - .map_axis(Axis(1), |row| row.argmax_skipnan().unwrap()) - .iter() - .map(|&x| x as i32) - .collect::>(); - println!("Token: {:?}", tokens); - all_tokens.extend(tokens.clone()); - } - - let ground_tokens = vec![ - 50258, 50259, 50359, 50363, 400, 370, 452, 7177, 6280, 1029, 406, 437, 428, 1941, 393, 360, - 337, 291, 1029, 437, 291, 393, 360, 337, 428, 1941, 13, 50257, - ]; - assert_eq!(all_tokens, ground_tokens); - Ok(()) -} diff --git a/crates/ratchet-nn/Cargo.toml b/crates/ratchet-nn/Cargo.toml index 0a9f3ea8..1fcd88fb 100644 --- a/crates/ratchet-nn/Cargo.toml +++ b/crates/ratchet-nn/Cargo.toml @@ -16,6 +16,7 @@ log.workspace = true derive-new = { workspace = true } half = { workspace = true } ratchet = { path = "../ratchet-core" } +ratchet-macros = { path = "../ratchet-macros" } wasm-bindgen = { workspace = true } wasm-bindgen-futures = { workspace = true } wasm-bindgen-test = { workspace = true } diff --git a/crates/ratchet-nn/src/activation.rs b/crates/ratchet-nn/src/activation.rs index 580360c8..f87e447e 100644 --- a/crates/ratchet-nn/src/activation.rs +++ b/crates/ratchet-nn/src/activation.rs @@ -1,6 +1,6 @@ -use ratchet::Tensor; - use crate::Module; +use ratchet::Tensor; +use ratchet_macros::scoped_module; #[derive(Debug, Clone, Copy, PartialEq, Default)] pub enum Activation { @@ -13,6 +13,7 @@ pub enum Activation { Swiglu, } +#[scoped_module] impl Module for Activation { type Input = Tensor; type Output = Tensor; diff --git a/crates/ratchet-nn/src/alibi.rs b/crates/ratchet-nn/src/alibi.rs index 621d1b8e..02da5a8e 100644 --- a/crates/ratchet-nn/src/alibi.rs +++ b/crates/ratchet-nn/src/alibi.rs @@ -1,4 +1,5 @@ use ratchet::Tensor; +use ratchet_macros::scoped_module; use crate::Module; @@ -12,6 +13,7 @@ pub struct AlibiInput { pub input: Tensor, } +#[scoped_module] impl Module for AlibiEmbedding { type Input = AlibiInput; type Output = Tensor; diff --git a/crates/ratchet-nn/src/dropout.rs b/crates/ratchet-nn/src/dropout.rs new file mode 100644 index 00000000..2f77ff7c --- /dev/null +++ b/crates/ratchet-nn/src/dropout.rs @@ -0,0 +1,40 @@ +use crate::{current_module_mode, Module, ModuleMode}; +use derive_new::new; +use ratchet::Tensor; +use ratchet_macros::scoped_module; + +/// Dropout layer that randomly zeroes some of the elements of the input tensor with probability `p` +/// during training, and rescales the remaining elements by a factor of `1/(1-p)`. +/// +/// This is a common regularization technique used in neural networks to prevent overfitting. +#[derive(Debug, Clone, new)] +pub struct Dropout { + /// Probability of an element to be zeroed. Value range: (0, 1) + p: f32, +} + +#[scoped_module] +impl Module for Dropout { + type Input = Tensor; + type Output = Tensor; + + fn schedule(&self, input: Self::Input) -> anyhow::Result { + if self.p <= 0.0 || current_module_mode() == ModuleMode::Eval { + return Ok(input); + } + + // Create a tensor of probabilities (1-p) to keep elements + let keep_prob = 1.0 - self.p; + let probs = Tensor::full::(&input.shape(), keep_prob, &input.device()); + + // Apply bernoulli sampling to get binary mask + let mask = probs.bernoulli()?; + + // Scale the mask by 1/(1-p) to maintain the expected value of the output + let scale = 1.0 / keep_prob; + let scaled_mask = mask.affine(scale, 0.0)?; + + // Apply the mask by multiplying element-wise with the input + input.mul(scaled_mask) + } +} diff --git a/crates/ratchet-nn/src/embedding.rs b/crates/ratchet-nn/src/embedding.rs index 6e8eaab2..415a6e51 100644 --- a/crates/ratchet-nn/src/embedding.rs +++ b/crates/ratchet-nn/src/embedding.rs @@ -1,5 +1,6 @@ use crate::Module; use ratchet::{shape, Shape, Tensor}; +use ratchet_macros::scoped_module; /// # Embedding /// @@ -21,6 +22,7 @@ impl Embedding { } } +#[scoped_module] impl Module for Embedding { type Input = Tensor; type Output = Tensor; diff --git a/crates/ratchet-nn/src/groupnorm.rs b/crates/ratchet-nn/src/groupnorm.rs index 4be45f2b..ed75a898 100644 --- a/crates/ratchet-nn/src/groupnorm.rs +++ b/crates/ratchet-nn/src/groupnorm.rs @@ -1,4 +1,5 @@ use ratchet::Tensor; +use ratchet_macros::scoped_module; #[derive(Debug, Clone, Copy, PartialEq)] pub struct GroupNormConfig { @@ -42,6 +43,7 @@ impl GroupNorm { } } +#[scoped_module] impl crate::Module for GroupNorm { type Input = Tensor; type Output = Tensor; diff --git a/crates/ratchet-nn/src/kv_cache.rs b/crates/ratchet-nn/src/kv_cache.rs index cb5a16eb..4d1456e1 100644 --- a/crates/ratchet-nn/src/kv_cache.rs +++ b/crates/ratchet-nn/src/kv_cache.rs @@ -24,6 +24,9 @@ pub struct KVCache { use_kv_cache: bool, masks: HashMap, device: Device, + n_layers: usize, + allocated: bool, + shape: Shape, } impl std::ops::Index for KVCache { @@ -42,14 +45,22 @@ impl KVCache { device: &Device, ) -> Self { let mut entries = Vec::with_capacity(n_layers as _); - for _ in 0..n_layers { - entries.push(KVEntry::allocate::(&shape, device)); + // TODO: This is really bad; look at actual patterns for how people do KV caches + let mut allocated = false; + if use_kv_cache { + for _ in 0..n_layers { + entries.push(KVEntry::allocate::(&shape, device)); + } + allocated = true; } KVCache { entries, masks: HashMap::default(), device: device.clone(), + n_layers: n_layers as _, use_kv_cache, + allocated, + shape, } } @@ -69,15 +80,32 @@ impl KVCache { } } + pub fn use_kv_cache(&self) -> bool { + self.use_kv_cache + } + + pub fn set_use_kv_cache(&mut self, use_kv_cache: bool) { + self.use_kv_cache = use_kv_cache; + if !use_kv_cache && self.allocated { + self.entries.clear(); + self.allocated = false; + } else if use_kv_cache && !self.allocated { + for _ in 0..self.n_layers { + self.entries + .push(KVEntry::allocate::(&self.shape, &self.device)); + } + self.allocated = true; + } + } + pub fn mask(&mut self, t: usize) -> anyhow::Result { if let Some(mask) = self.masks.get(&t) { log::debug!("Using existing mask for {:?}", t); Ok(mask.clone()) } else { log::debug!("Creating mask for {:?}", t); - log::debug!("masks: {:?}", self.masks); let ones = Tensor::ones::(&shape![t, t], &self.device); - let mask = ones.triu(Some(1))?; + let mask = ones.tril(None)?; self.masks.insert(t, mask.clone()); Ok(mask) } diff --git a/crates/ratchet-nn/src/lib.rs b/crates/ratchet-nn/src/lib.rs index e9433e05..7dca73e2 100644 --- a/crates/ratchet-nn/src/lib.rs +++ b/crates/ratchet-nn/src/lib.rs @@ -1,5 +1,6 @@ mod activation; mod alibi; +mod dropout; mod embedding; mod groupnorm; mod init; @@ -11,12 +12,14 @@ mod norm; mod optim; mod rope; mod sinusoidal; +mod training_context; mod util; mod var_builder; mod var_map; pub use activation::*; pub use alibi::*; +pub use dropout::*; pub use embedding::*; pub use groupnorm::*; pub use init::*; @@ -28,6 +31,7 @@ pub use norm::*; pub use optim::*; pub use rope::*; pub use sinusoidal::*; +pub use training_context::*; pub use util::*; pub use var_builder::*; pub use var_map::*; @@ -45,6 +49,8 @@ use ratchet::Tensor; pub trait Module { type Input; type Output; + + fn module_name(&self) -> &str; fn schedule(&self, input: Self::Input) -> anyhow::Result; } diff --git a/crates/ratchet-nn/src/linear.rs b/crates/ratchet-nn/src/linear.rs index 7734168f..3e71f067 100644 --- a/crates/ratchet-nn/src/linear.rs +++ b/crates/ratchet-nn/src/linear.rs @@ -1,5 +1,6 @@ use maybe_async::maybe_async; use ratchet::{shape, Tensor}; +use ratchet_macros::scoped_module; use crate::Module; @@ -13,6 +14,7 @@ pub struct Linear { b: Option, } +#[scoped_module] impl Module for Linear { type Input = Tensor; type Output = Tensor; @@ -79,7 +81,7 @@ pub async fn linear_b( } } -#[cfg(test)] +#[cfg(all(test, feature = "pyo3"))] mod tests { use crate::{Module, VarBuilder, VarMap}; diff --git a/crates/ratchet-nn/src/loss.rs b/crates/ratchet-nn/src/loss.rs index ea6e66d9..5c620489 100644 --- a/crates/ratchet-nn/src/loss.rs +++ b/crates/ratchet-nn/src/loss.rs @@ -1,6 +1,7 @@ -use ratchet::Tensor; +use ratchet::{DType, ScopePusher, Tensor}; pub fn nll(inp: Tensor, target: Tensor) -> anyhow::Result { + let _scope_guard = ScopePusher::new("loss:nll"); let b_sz = match &target.shape().to_vec()[..] { &[b_sz] => b_sz, dims => anyhow::bail!("the target tensor should have a single dimension ({dims:?})"), @@ -14,11 +15,118 @@ pub fn nll(inp: Tensor, target: Tensor) -> anyhow::Result { dims => anyhow::bail!("the target tensor should have two dimensions ({dims:?})"), } inp.gather(target.clone().unsqueeze(1)?, 1)? - .sum_all()? .affine(-1f32 / b_sz as f32, 0.) } +pub fn nll_masked(inp: Tensor, target: Tensor) -> anyhow::Result { + let _scope_guard = ScopePusher::new("loss:nll_masked"); + let b_sz = match &target.shape().to_vec()[..] { + &[b_sz] => b_sz, + dims => anyhow::bail!("the target tensor should have a single dimension ({dims:?})"), + }; + match &inp.shape().to_vec()[..] { + &[inp_b_sz, _] => { + if inp_b_sz != b_sz { + anyhow::bail!("batch size mismatch between inp ({inp_b_sz}) and target ({b_sz})") + } + } + dims => anyhow::bail!("the target tensor should have two dimensions ({dims:?})"), + } + + // We do a bunch of work here to allow ignoring tokens in the target. + let ignore_index = -100; + let mask = target + .clone() + .ne(Tensor::full(target.shape(), ignore_index, target.device()))?; + + // Note here that we seem to be able to get away with passing negative indices to gather. + // If we were more careful about this, we'd replace the indices with 0s where the mask is 0, + // before passing them to gather. + + let per_sample_loss = inp + .gather(target.clone().unsqueeze(1)?, 1)? + .affine(-1f32, 0.)?; + let mask_unsqueezed = mask.clone().unsqueeze(1)?; + let masked_loss = per_sample_loss + .clone() + .mul(mask_unsqueezed.cast(DType::F32)?)?; + + let valid_count = mask.cast(DType::F32)?.sum_all()?; + + masked_loss.div(valid_count.cast(DType::F32)?) +} + +/// Computes label-smoothed cross-entropy for a flattened `[batch_size, vocab_size]` log-softmax +/// tensor `log_probs`, together with a corresponding `target` of shape `[batch_size]`. +/// +/// `alpha` is the smoothing parameter in `[0, 1]`. If `alpha == 0.0`, this is just ordinary NLL. +pub fn label_smoothed_nll(log_probs: Tensor, target: Tensor, alpha: f32) -> anyhow::Result { + let _scope_guard = ScopePusher::new("loss:nll_label_smoothed"); + let b_sz = match &target.shape().to_vec()[..] { + &[b_sz] => b_sz, + dims => { + anyhow::bail!("label_smoothed_nll: target must be [batch_size], got shape {dims:?}") + } + }; + let shape_lp = log_probs.shape().to_vec(); + if shape_lp.len() != 2 { + anyhow::bail!( + "label_smoothed_nll: log_probs must be rank-2 [batch_size, vocab_size], got {shape_lp:?}" + ); + } + let (inp_b_sz, vocab_size) = (shape_lp[0], shape_lp[1]); + if inp_b_sz != b_sz { + anyhow::bail!( + "label_smoothed_nll: batch size mismatch between log_probs ({inp_b_sz}) and target ({b_sz})" + ); + } + + // Check for ignored tokens (often `-100` in NLP). + let ignore_index = -100; + let mask = target + .clone() + .ne(Tensor::full(target.shape(), ignore_index, target.device()))? + .cast(ratchet::DType::F32)?; + + // Gather the negative log-prob for the correct class: + // nll_loss[i] = -log_probs[i, target[i]] (for each token i). + let nll_gathered = log_probs + .clone() + .gather(target.clone().unsqueeze(1)?, 1)? // shape [batch_size, 1] + .affine(-1.0, 0.0)?; // multiply by -1 + + // Mask out ignored tokens (multiply by 0 where masked=0). + let nll_masked = nll_gathered.mul(mask.clone().unsqueeze(1)?)?; + + // We'll also average over only the valid tokens: + let valid_count = mask.clone().sum_all()?; // shape [] + + // (1) Ordinary cross-entropy term (averaged). + let nll_loss = nll_masked.div(valid_count.clone())?; + + // (2) Uniform penalty term, also masked. + // + // For label smoothing, we pretend a small fraction α of the time + // we want the “average” log-prob over all classes, not just the correct one. + // i.e. uniform_loss = - average over (vocab_size) of log_probs, restricted to masked positions. + let all_probs_masked = log_probs.mul(mask.unsqueeze(1)?)?; + let sum_log_probs = all_probs_masked.sum(&[1])?; + // Now shape [batch_size], each entry is sum_{v in vocab} log_probs[i, v]. + // Negative average per token: + let neg_avg_log_prob = sum_log_probs.affine(-1.0 / vocab_size as f32, 0.0)?; + let uniform_loss = neg_avg_log_prob.sum_all()?.div(valid_count)?; + + // Combine with alpha + // final = (1 - alpha) * nll + alpha * uniform_term + let final_loss = nll_loss + .affine(1.0 - alpha, 0.0)? + .add(uniform_loss.affine(alpha, 0.0)?)?; + + Ok(final_loss) +} + pub fn log_softmax(xs: Tensor, d: usize) -> anyhow::Result { + let _scope_guard = ScopePusher::new("loss:log_softmax"); let max = xs.clone().max_keepdim(d)?; let diff = xs.clone().sub(max)?; let sum_exp = diff.clone().exp()?.sum_keepdim(&[d])?; @@ -27,11 +135,12 @@ pub fn log_softmax(xs: Tensor, d: usize) -> anyhow::Result { } pub fn cross_entropy(inp: Tensor, target: Tensor) -> anyhow::Result { + let _scope_guard = ScopePusher::new("loss:cross_entropy"); if inp.rank() != 2 { anyhow::bail!("cross_entropy expects an input tensor of rank 2") } let inp = log_softmax(inp, 1)?; - nll(inp, target) + nll(inp, target)?.sum_all() } #[cfg(all(test, feature = "pyo3"))] diff --git a/crates/ratchet-nn/src/norm.rs b/crates/ratchet-nn/src/norm.rs index 3e53f9fd..d650ac8c 100644 --- a/crates/ratchet-nn/src/norm.rs +++ b/crates/ratchet-nn/src/norm.rs @@ -1,5 +1,6 @@ use maybe_async::maybe_async; use ratchet::{shape, DType, Tensor}; +use ratchet_macros::scoped_module; #[derive(Debug, Clone, Copy, PartialEq)] pub struct LayerNormConfig { @@ -52,6 +53,7 @@ impl LayerNorm { } } +#[scoped_module] impl crate::Module for LayerNorm { type Input = Tensor; type Output = Tensor; @@ -122,6 +124,7 @@ impl RMSNorm { } } +#[scoped_module] impl crate::Module for RMSNorm { type Input = Tensor; type Output = Tensor; @@ -143,7 +146,7 @@ pub async fn rms_norm(size: usize, eps: f32, vb: crate::VarBuilder<'_>) -> anyho Ok(RMSNorm::new(weight, eps)) } -#[cfg(test)] +#[cfg(feature = "pyo3")] mod tests { use super::{layer_norm, LayerNorm, LayerNormConfig}; use crate::{Module, VarBuilder, VarMap}; diff --git a/crates/ratchet-nn/src/optim.rs b/crates/ratchet-nn/src/optim.rs index 4ed86443..fd8e9679 100644 --- a/crates/ratchet-nn/src/optim.rs +++ b/crates/ratchet-nn/src/optim.rs @@ -1,8 +1,6 @@ -#[cfg(target_arch = "wasm32")] -use async_trait::async_trait; use half::{bf16, f16}; use maybe_async::maybe_async; -use ratchet::{DType, Device, GradStore, Var}; +use ratchet::{DType, Device, GradStore, ScopePusher, Var}; #[maybe_async(AFIT)] #[cfg_attr(target_arch = "wasm32", async_trait::async_trait)] @@ -67,16 +65,20 @@ impl Optimizer for SGD { async fn step(&mut self, grads: &ratchet::GradStore, device: &Device) -> anyhow::Result<()> { let mut updates = Vec::new(); - for (_, var) in &self.vars { - if let Some(grad) = grads.get(var.as_tensor()) { - let update = - (var.as_tensor().clone() - (grad.clone() * self.learning_rate as f32)?)?; - updates.push(var.set(update)); + { + let _scope_guard = ScopePusher::new("optim:SGD"); + for (_, var) in &self.vars { + let _scope_guard = optim_var_scope_guard(var); + if let Some(grad) = grads.get(var.as_tensor()) { + let update = + (var.as_tensor().clone() - (grad.clone() * self.learning_rate as f32)?)?; + updates.push(var.set(update)); + } } } if let Ok(gpu_device) = device.try_gpu() { - gpu_device.mark_step()?; + gpu_device.mark_step().await; } Ok(()) @@ -171,46 +173,49 @@ impl Optimizer for AdamW { } async fn step(&mut self, grads: &ratchet::GradStore, device: &Device) -> anyhow::Result<()> { - self.step_t += 1; - let lr = self.params.lr; - let lambda = self.params.weight_decay; - let lr_lambda = lr * lambda; - let beta1 = self.params.beta1; - let beta2 = self.params.beta2; - let scale_m = 1f64 / (1f64 - beta1.powi(self.step_t as i32)); - let scale_v = 1f64 / (1f64 - beta2.powi(self.step_t as i32)); - // This makes sure we keep references to the copy tensors. let mut updates = Vec::new(); - - for var in self.vars.iter_mut() { - let theta = &var.var; - let m = &var.first_moment; - let v = &var.second_moment; - - // println!("Optimizer stepping: {:?}", var.label); - // println!("Theta op: {:?}", theta.as_tensor().op()); - // println!("Theta id: {:?}", theta.as_tensor().id()); - - if let Some(g) = grads.get(theta.as_tensor()) { - let next_m = ((m.as_tensor().clone() * beta1 as f32)? - + (g.clone() * (1.0 - beta1 as f32))?)?; - let next_v = ((v.as_tensor().clone() * beta2 as f32)? - + (g.clone().square()? * (1.0 - beta2 as f32))?)?; - let m_hat = (next_m.clone() * scale_m as f32)?; - let v_hat = (next_v.clone() * scale_v as f32)?; - let next_theta = (theta.as_tensor().clone() * (1f32 - lr_lambda as f32))?; - let adjusted_grad = (m_hat / (v_hat.sqrt()? + self.params.eps as f32)?)?; - let next_theta = (next_theta - (adjusted_grad.clone() * lr as f32)?)?; - - // This ensures we keep references to the copy tensors. - updates.push((theta.set(next_theta), m.set(next_m), v.set(next_v))); + { + let _scope_guard = ScopePusher::new("optim:AdamW"); + self.step_t += 1; + let lr = self.params.lr; + let lambda = self.params.weight_decay; + let lr_lambda = lr * lambda; + let beta1 = self.params.beta1; + let beta2 = self.params.beta2; + let scale_m = 1f64 / (1f64 - beta1.powi(self.step_t as i32)); + let scale_v = 1f64 / (1f64 - beta2.powi(self.step_t as i32)); + + for var in self.vars.iter_mut() { + let _scope_guard = optim_var_scope_guard(&var.var); + let theta = &var.var; + let m = &var.first_moment; + let v = &var.second_moment; + + // println!("Optimizer stepping: {:?}", var.label); + // println!("Theta op: {:?}", theta.as_tensor().op()); + // println!("Theta id: {:?}", theta.as_tensor().id()); + + if let Some(g) = grads.get(theta.as_tensor()) { + let next_m = ((m.as_tensor().clone() * beta1 as f32)? + + (g.clone() * (1.0 - beta1 as f32))?)?; + let next_v = ((v.as_tensor().clone() * beta2 as f32)? + + (g.clone().square()? * (1.0 - beta2 as f32))?)?; + let m_hat = (next_m.clone() * scale_m as f32)?; + let v_hat = (next_v.clone() * scale_v as f32)?; + let next_theta = (theta.as_tensor().clone() * (1f32 - lr_lambda as f32))?; + let adjusted_grad = (m_hat / (v_hat.sqrt()? + self.params.eps as f32)?)?; + let next_theta = (next_theta - (adjusted_grad.clone() * lr as f32)?)?; + + // This ensures we keep references to the copy tensors. + updates.push((theta.set(next_theta), m.set(next_m), v.set(next_v))); + } } } // Finalize all the tensors we just built above. if let Ok(gpu) = device.try_gpu() { - gpu.mark_step()?; + gpu.mark_step().await?; } Ok(()) @@ -234,3 +239,16 @@ impl AdamW { self.params = params; } } + +fn optim_var_scope_guard(var: &Var) -> ScopePusher { + ScopePusher::new( + format!( + "for:({})", + var.as_tensor() + .scope() + .as_ref() + .unwrap_or(&"unknown".to_string()) + ) + .as_str(), + ) +} diff --git a/crates/ratchet-nn/src/rope.rs b/crates/ratchet-nn/src/rope.rs index 7e06a42d..a7195a63 100644 --- a/crates/ratchet-nn/src/rope.rs +++ b/crates/ratchet-nn/src/rope.rs @@ -1,4 +1,5 @@ use ratchet::Tensor; +use ratchet_macros::scoped_module; use crate::Module; @@ -33,6 +34,7 @@ pub struct RotaryInput { pub offset: usize, } +#[scoped_module] impl Module for RotaryEmbedding { type Input = RotaryInput; type Output = Tensor; diff --git a/crates/ratchet-nn/src/sinusoidal.rs b/crates/ratchet-nn/src/sinusoidal.rs index 92157d4b..6d25f246 100644 --- a/crates/ratchet-nn/src/sinusoidal.rs +++ b/crates/ratchet-nn/src/sinusoidal.rs @@ -1,4 +1,5 @@ use ratchet::{rvec, shape, DType, Tensor}; +use ratchet_macros::scoped_module; use crate::Module; @@ -29,6 +30,7 @@ impl SinusoidalEmbedding { } } +#[scoped_module] impl Module for SinusoidalEmbedding { type Input = SinusoidalInput; type Output = Tensor; diff --git a/crates/ratchet-nn/src/training_context.rs b/crates/ratchet-nn/src/training_context.rs new file mode 100644 index 00000000..68772750 --- /dev/null +++ b/crates/ratchet-nn/src/training_context.rs @@ -0,0 +1,43 @@ +use std::cell::RefCell; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum ModuleMode { + Train, + Eval, +} + +thread_local! { + static CURRENT_MODE: RefCell = RefCell::new(ModuleMode::Train); +} + +// Functions to get/set the mode +pub fn set_train_mode() { + CURRENT_MODE.with(|mode| *mode.borrow_mut() = ModuleMode::Train); +} + +pub fn set_eval_mode() { + CURRENT_MODE.with(|mode| *mode.borrow_mut() = ModuleMode::Eval); +} + +pub fn current_module_mode() -> ModuleMode { + CURRENT_MODE.with(|mode| *mode.borrow()) +} + +/// Context manager for scoped mode changes +pub struct ModuleModeGuard { + previous: ModuleMode, +} + +impl ModuleModeGuard { + pub fn new(mode: ModuleMode) -> Self { + let previous = current_module_mode(); + CURRENT_MODE.with(|m| *m.borrow_mut() = mode); + Self { previous } + } +} + +impl Drop for ModuleModeGuard { + fn drop(&mut self) { + CURRENT_MODE.with(|mode| *mode.borrow_mut() = self.previous); + } +} diff --git a/crates/ratchet-nn/src/var_map.rs b/crates/ratchet-nn/src/var_map.rs index f6c9dd0d..0c0983c1 100644 --- a/crates/ratchet-nn/src/var_map.rs +++ b/crates/ratchet-nn/src/var_map.rs @@ -69,11 +69,10 @@ impl VarMap { } #[cfg(target_arch = "wasm32")] - async fn download_safetensors( + async fn create_safetensors_download_url( &self, - file_name: &str, data: Vec<(String, Tensor)>, - ) -> anyhow::Result<(), JsValue> { + ) -> anyhow::Result { // Convert (String, Tensor) -> (&String, &Tensor) for serialization let data_ref: Vec<(&String, &Tensor)> = data.iter().map(|(k, v)| (k, v)).collect(); @@ -88,29 +87,12 @@ impl VarMap { // Create a URL for the Blob let url = Url::create_object_url_with_blob(&blob)?; - // Create an anchor element and trigger the download - let document = web_sys::window().unwrap().document().unwrap(); - let a: HtmlAnchorElement = document.create_element("a")?.dyn_into()?; - a.set_href(&url); - a.set_download(file_name); - a.style().set_property("display", "none")?; - document.body().unwrap().append_child(&a)?; - a.click(); - document.body().unwrap().remove_child(&a)?; - - // Revoke the object URL to free memory - Url::revoke_object_url(&url)?; - - Ok(()) + Ok(url) } /// Download the gradients as a safetensors file using web APIs. #[cfg(target_arch = "wasm32")] - pub async fn download_grads( - &self, - file_name: &str, - grads: &GradStore, - ) -> anyhow::Result<(), JsValue> { + pub async fn grads_download_url(&self, grads: &GradStore) -> anyhow::Result { let tensor_data = self.data.lock().unwrap(); let data = Arc::new(Mutex::new(Vec::new())); let mut futures = Vec::new(); @@ -135,15 +117,13 @@ impl VarMap { let data = Arc::try_unwrap(data).unwrap().into_inner().unwrap(); // Use the shared helper to download the safetensors data - self.download_safetensors(file_name, data).await?; - - Ok(()) + self.create_safetensors_download_url(data).await } /// Download the variables (instead of grads) as a safetensors file using web APIs. /// This avoids logic duplication by calling the same `_download_safetensors` helper. #[cfg(target_arch = "wasm32")] - pub async fn download(&self, file_name: &str) -> anyhow::Result<(), JsValue> { + pub async fn download_url(&self) -> anyhow::Result { let tensor_data = self.data.lock().unwrap(); let data = Arc::new(Mutex::new(Vec::new())); let mut futures = Vec::new(); @@ -168,9 +148,7 @@ impl VarMap { let data = Arc::try_unwrap(data).unwrap().into_inner().unwrap(); // Use the shared helper - self.download_safetensors(file_name, data).await?; - - Ok(()) + self.create_safetensors_download_url(data).await } /// Set a named variable to some value. diff --git a/crates/ratchet-web-train/.gitignore b/crates/ratchet-web-train/.gitignore new file mode 100644 index 00000000..7dfa3a84 --- /dev/null +++ b/crates/ratchet-web-train/.gitignore @@ -0,0 +1 @@ +test_suite.json \ No newline at end of file diff --git a/crates/ratchet-web/Cargo.toml b/crates/ratchet-web-train/Cargo.toml similarity index 54% rename from crates/ratchet-web/Cargo.toml rename to crates/ratchet-web-train/Cargo.toml index c0b5ebc3..98443f89 100644 --- a/crates/ratchet-web/Cargo.toml +++ b/crates/ratchet-web-train/Cargo.toml @@ -1,11 +1,12 @@ [package] -name = "ratchet-web" -version = "0.3.0" +name = "ratchet-web-train" +version = "0.0.0" edition = "2021" license = "MIT" -description = "A web-first, cross-platform ML framework." -keywords = ["llm","wasm","transformers","webgpu","ml","machine-learning","deep-learning"] -repository = "https://github.com/FL33TW00D/ratchet" +repository = "https://github.com/vinhowe/ratchet-backward" + +[features] +debug = ["ratchet-nn/debug"] [lib] crate-type = ["cdylib", "rlib"] @@ -16,58 +17,50 @@ default-target = "wasm32-unknown-unknown" [package.metadata.wasm-pack.profile.dev.wasm-bindgen] debug-js-glue = true demangle-name-section = true -dwarf-debug-info = true +dwarf-debug-info = true [package.metadata.wasm-pack.profile.release] -wasm-opt = ['-O3', '--enable-simd'] +wasm-opt = [ + '-O4', + '--enable-simd', + '--flexible-inline-max-function-size', + '4294967295', +] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] ratchet-models = { path = "../ratchet-models" } -ratchet-hub = { path = "../ratchet-hub" } -ratchet-loader = { path = "../ratchet-loader" } +ratchet-nn = { path = "../ratchet-nn" } +ratchet-datasets = { path = "../ratchet-datasets" } +ratchet = { path = "../ratchet-core" } wasm-bindgen = { workspace = true } wasm-bindgen-futures = { workspace = true } js-sys = { workspace = true } -indexed_db_futures = { workspace = true } thiserror.workspace = true anyhow.workspace = true serde = { workspace = true } +serde_json = { workspace = true } serde-wasm-bindgen = { workspace = true } console_error_panic_hook = { workspace = true } console_log = { workspace = true, features = ["color"] } log.workspace = true -hound = { workspace = true } -fern = { workspace = true } chrono = { workspace = true } -uuid = { workspace = true, features = ["v4", "serde"] } -tokenizers = { version = "0.19.1", default-features = false, features=["unstable_wasm"] } +fern = { workspace = true } +tokenizers = { version = "0.19.1", default-features = false, features = [ + "unstable_wasm", +] } futures = "0.3.30" +async-trait = { workspace = true } [dependencies.web-sys] features = [ 'console', - 'Headers', - 'Request', - 'RequestInit', - 'RequestMode', - 'Response', - 'ReadableStream', - 'ReadableStreamGetReaderOptions', - 'ReadableStreamReaderMode', 'Window', 'Navigator', - 'StorageManager', - 'Cache', - 'CacheStorage', - 'IdbKeyRange', ] workspace = true -[target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.2.6", features = ["js"] } - [dev-dependencies] wasm-bindgen-test.workspace = true -ratchet-hub = { path = "../ratchet-hub" } - +serde_json = { workspace = true } +ndarray = { workspace = true } diff --git a/crates/ratchet-web-train/README.md b/crates/ratchet-web-train/README.md new file mode 100644 index 00000000..8792012a --- /dev/null +++ b/crates/ratchet-web-train/README.md @@ -0,0 +1,2 @@ +# ratchet-web-train + diff --git a/crates/ratchet-web-train/src/lib.rs b/crates/ratchet-web-train/src/lib.rs new file mode 100644 index 00000000..56d76b45 --- /dev/null +++ b/crates/ratchet-web-train/src/lib.rs @@ -0,0 +1,6 @@ +#![cfg(target_arch = "wasm32")] +mod model; +#[cfg(test)] +mod test_ops; +#[cfg(test)] +mod test_utils; diff --git a/crates/ratchet-web-train/src/model.rs b/crates/ratchet-web-train/src/model.rs new file mode 100644 index 00000000..816be334 --- /dev/null +++ b/crates/ratchet-web-train/src/model.rs @@ -0,0 +1,703 @@ +use anyhow::Result; +use async_trait::async_trait; +use js_sys::Function; +use ratchet::{ + reset_scope_context, shape, DType, Device, DeviceRequest, GradStore, StepLog, Tensor, Var, +}; +use ratchet_models::gpt2::generate; +use ratchet_models::gpt2::{Config, GPT2Input, PositionalEncoding}; +use ratchet_models::gpt2::{LayerNormPosition, GPT2}; +use ratchet_nn::{ + clip_grad_norm, cross_entropy, label_smoothed_nll, log_softmax, nll, nll_masked, Activation, + AdamW, ConstantLR, CosineAnnealingLR, LRScheduler, LRSchedulerCore, LinearLR, Module, + Optimizer, ParamsAdamW, VarBuilder, VarMap, SGD, +}; +use ratchet_nn::{ModuleMode, ModuleModeGuard}; +use serde::{Deserialize, Serialize}; +use std::cell::RefCell; +use std::iter::Iterator; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(start)] +pub fn start() { + console_error_panic_hook::set_once(); + let logger = fern::Dispatch::new() + .format(|out, message, record| { + out.finish(format_args!( + "{}[{}][{}] {}", + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), + record.target(), + record.level(), + message + )) + }) + .level_for("tokenizers", log::LevelFilter::Off) + .level(log::LevelFilter::Info) + .chain(fern::Output::call(console_log::log)) + .apply(); + match logger { + Ok(_) => log::info!("Logging initialized."), + Err(error) => eprintln!("Error initializing logging: {:?}", error), + } +} + +#[derive(Serialize, Deserialize)] +pub struct OptimizerConfig { + pub optimizer_type: String, // "adamw" or "sgd" + pub lr: f64, + #[serde(default = "default_beta1")] + pub beta1: f64, + #[serde(default = "default_beta2")] + pub beta2: f64, + #[serde(default = "default_eps")] + pub eps: f64, + #[serde(default = "default_weight_decay")] + pub weight_decay: f64, + #[serde(default = "default_momentum")] + pub momentum: f64, // For SGD + #[serde(default = "default_scheduler_type")] + pub scheduler_type: String, // "none", "constant", "linear", "cosine" + #[serde(default = "default_scheduler_factor")] + pub scheduler_factor: f64, // For constant/linear scheduler + #[serde(default = "default_scheduler_steps")] + pub scheduler_steps: usize, // For all schedulers + #[serde(default = "default_scheduler_eta_min")] + pub scheduler_eta_min: f64, // For cosine scheduler +} + +fn default_beta1() -> f64 { + 0.9 +} +fn default_beta2() -> f64 { + 0.999 +} +fn default_eps() -> f64 { + 1e-8 +} +fn default_weight_decay() -> f64 { + 0.0 +} +fn default_momentum() -> f64 { + 0.0 +} +fn default_scheduler_type() -> String { + "none".to_string() +} +fn default_scheduler_factor() -> f64 { + 1.0 +} +fn default_scheduler_steps() -> usize { + 1000 +} +fn default_scheduler_eta_min() -> f64 { + 0.0 +} + +#[derive(Serialize, Deserialize)] +#[serde(untagged)] +pub enum JsDebugSelection { + String(String), + Array(Vec), +} + +#[derive(Serialize, Deserialize)] +pub struct JsStepLogConfig { + #[serde(default = "default_profiling")] + pub profiling: bool, + #[serde(default = "default_debug_selection")] + pub debug_selection: Option, +} + +fn default_profiling() -> bool { + false +} + +fn default_debug_selection() -> Option { + None +} + +#[derive(Serialize, Deserialize)] +pub struct TrainerConfig { + pub vocab_size: usize, + pub n_embd: usize, + pub n_layer: usize, + pub n_head: usize, + pub block_size: usize, + pub batch_size: usize, + #[serde(default = "default_caching_enabled")] + pub caching_enabled: bool, + #[serde(default = "default_inplace_support")] + pub inplace_support: bool, + #[serde(default = "default_optimizer_config")] + pub optimizer: OptimizerConfig, + #[serde(default = "default_activation")] + pub activation: String, + #[serde(default = "default_attention_only")] + pub attention_only: bool, + #[serde(default = "default_positional_encoding")] + pub positional_encoding: String, + #[serde(default = "default_layernorm_position")] + pub layernorm_position: String, + #[serde(default = "default_seed")] + pub seed: Option, + #[serde(default = "default_label_smoothing")] + pub label_smoothing: f32, + #[serde(default = "default_embd_pdrop")] + pub embd_pdrop: f32, + #[serde(default = "default_attn_pdrop")] + pub attn_pdrop: f32, + #[serde(default = "default_resid_pdrop")] + pub resid_pdrop: f32, +} + +fn default_caching_enabled() -> bool { + true +} + +fn default_inplace_support() -> bool { + true +} + +fn default_optimizer_config() -> OptimizerConfig { + OptimizerConfig { + optimizer_type: "adamw".to_string(), + lr: 1e-3, + beta1: default_beta1(), + beta2: default_beta2(), + eps: default_eps(), + weight_decay: default_weight_decay(), + momentum: default_momentum(), + scheduler_type: default_scheduler_type(), + scheduler_factor: default_scheduler_factor(), + scheduler_steps: default_scheduler_steps(), + scheduler_eta_min: default_scheduler_eta_min(), + } +} + +fn default_activation() -> String { + "gelu".to_string() +} + +fn default_attention_only() -> bool { + false +} + +fn default_positional_encoding() -> String { + "learned".to_string() +} + +fn default_layernorm_position() -> String { + "pre".to_string() +} + +fn default_embd_pdrop() -> f32 { + 0.1 +} + +fn default_attn_pdrop() -> f32 { + 0.1 +} + +fn default_resid_pdrop() -> f32 { + 0.1 +} + +fn default_seed() -> Option { + None +} + +fn default_label_smoothing() -> f32 { + 0.0 +} + +fn string_to_activation(s: &str) -> Activation { + match s.to_lowercase().as_str() { + "gelu" => Activation::Gelu, + "relu" => Activation::Relu, + "relu2" => Activation::Relu2, + "silu" => Activation::Silu, + "sigmoid" => Activation::Sigmoid, + "swiglu" => Activation::Swiglu, + _ => Activation::Gelu, + } +} + +#[derive(Debug, Clone)] +pub enum OptimizerConfigEnum { + AdamW(ParamsAdamW), + SGD(f64), +} + +pub enum OptimizerEnum { + AdamW(AdamW), + SGD(SGD), +} + +#[async_trait] +impl Optimizer for OptimizerEnum { + type Config = OptimizerConfigEnum; + + fn new(vars: Vec<(Option, Var)>, config: Self::Config) -> anyhow::Result { + match config { + OptimizerConfigEnum::AdamW(params) => Ok(Self::AdamW(AdamW::new(vars, params)?)), + OptimizerConfigEnum::SGD(params) => Ok(Self::SGD(SGD::new(vars, params)?)), + } + } + + async fn step(&mut self, grads: &GradStore, device: &Device) -> anyhow::Result<()> { + match self { + OptimizerEnum::AdamW(opt) => opt.step(grads, device).await, + OptimizerEnum::SGD(opt) => opt.step(grads, device).await, + } + } + + fn learning_rate(&self) -> f64 { + match self { + OptimizerEnum::AdamW(opt) => opt.learning_rate(), + OptimizerEnum::SGD(opt) => opt.learning_rate(), + } + } + + fn set_learning_rate(&mut self, lr: f64) { + match self { + OptimizerEnum::AdamW(opt) => opt.set_learning_rate(lr), + OptimizerEnum::SGD(opt) => opt.set_learning_rate(lr), + } + } +} + +#[wasm_bindgen] +pub struct Trainer { + model: GPT2, + varmap: VarMap, + optimizer: Box + Send + Sync>, + device: Device, + config: TrainerConfig, +} + +#[wasm_bindgen] +impl Trainer { + #[wasm_bindgen(constructor)] + pub async fn new(config: JsValue) -> Result { + let cfg: TrainerConfig = + serde_wasm_bindgen::from_value(config).map_err(|e| JsValue::from(e.to_string()))?; + + let device = Device::request_device(DeviceRequest::GPU) + .await + .map_err(|e| e.to_string())?; + + // Set seed on device if provided + if let Some(seed) = cfg.seed { + device.set_seed(seed); + } + + let varmap = VarMap::new(); + let vb = VarBuilder::from_varmap(&varmap, DType::F32, &device); + + let gpt2_config = Config { + vocab_size: cfg.vocab_size, + hidden_act: string_to_activation(&cfg.activation), + n_embd: cfg.n_embd, + n_layer: cfg.n_layer, + n_head: cfg.n_head, + block_size: cfg.block_size, + attention_only: cfg.attention_only, + positional_encoding: match cfg.positional_encoding.to_lowercase().as_str() { + "rope" => PositionalEncoding::RoPE, + "alibi" => PositionalEncoding::ALiBi, + "sinusoidal" => PositionalEncoding::Sinusoidal, + _ => PositionalEncoding::Learned, + }, + layernorm_position: match cfg.layernorm_position.to_lowercase().as_str() { + "pre" => LayerNormPosition::Pre, + "post" => LayerNormPosition::Post, + "none" => LayerNormPosition::None, + _ => LayerNormPosition::Pre, + }, + embd_pdrop: cfg.embd_pdrop, + attn_pdrop: cfg.attn_pdrop, + resid_pdrop: cfg.resid_pdrop, + }; + + device + .try_gpu() + .unwrap() + .set_caching_enabled(cfg.caching_enabled); + + device + .try_gpu() + .unwrap() + .set_inplace_support(cfg.inplace_support); + + let model = GPT2::new(&gpt2_config, vb, false) + .await + .map_err(|e| e.to_string())?; + + let vars = varmap + .all_labeled_vars() + .iter() + .map(|(label, var)| (Some(label.to_owned()), var.to_owned())) + .collect::>(); + + let optimizer_config = match cfg.optimizer.optimizer_type.to_lowercase().as_str() { + "sgd" => OptimizerConfigEnum::SGD(cfg.optimizer.lr), + _ => OptimizerConfigEnum::AdamW(ParamsAdamW { + lr: cfg.optimizer.lr, + beta1: cfg.optimizer.beta1, + beta2: cfg.optimizer.beta2, + eps: cfg.optimizer.eps, + weight_decay: cfg.optimizer.weight_decay, + }), + }; + + let base_optimizer = + OptimizerEnum::new(vars, optimizer_config).map_err(|e| e.to_string())?; + + // Wrap the optimizer in the selected scheduler + let optimizer: Box + Send + Sync> = + match cfg.optimizer.scheduler_type.to_lowercase().as_str() { + "constant" => Box::new(ConstantLR::new( + base_optimizer, + cfg.optimizer.scheduler_factor, + cfg.optimizer.scheduler_steps, + )), + "linear" => Box::new(LinearLR::new( + base_optimizer, + 1.0, + cfg.optimizer.scheduler_factor, + cfg.optimizer.scheduler_steps, + )), + "cosine" => Box::new(CosineAnnealingLR::new( + base_optimizer, + cfg.optimizer.scheduler_steps, + cfg.optimizer.scheduler_eta_min, + )), + _ => Box::new(NoopScheduler::new(base_optimizer)), + }; + + Ok(Trainer { + model, + varmap, + optimizer, + device, + config: cfg, + }) + } + + async fn forward(&mut self, input: Vec>) -> anyhow::Result<(Tensor, Tensor)> { + let batch_size = input.len(); + let seq_len = input[0].len(); + + let input_flat: Vec = input.into_iter().flatten().collect(); + let input_tensor = + Tensor::from_data(input_flat, shape![batch_size, seq_len], self.device.clone()); + + let (logits, attn_masks) = self.model.schedule(GPT2Input { + x: input_tensor, + index_pos: 0, + })?; + Ok((logits, attn_masks)) + } + + #[wasm_bindgen(js_name = "forward")] + pub async fn forward_js(&mut self, input: JsValue) -> Result { + reset_scope_context(); + let input: Vec> = + serde_wasm_bindgen::from_value(input).map_err(|e| JsValue::from(e.to_string()))?; + let (logits, _) = self.forward(input).await.map_err(|e| e.to_string())?; + + let logits_cpu = logits.to(&Device::CPU).await.map_err(|e| e.to_string())?; + let logits_shape = logits_cpu.shape().to_vec(); + let logits_data = logits_cpu + .to_vec::() + .await + .map_err(|e| e.to_string())?; + + Ok( + serde_wasm_bindgen::to_value(&(logits_data, logits_shape)) + .map_err(|e| e.to_string())?, + ) + } + + /// Train on a single batch of data provided directly from JavaScript + #[wasm_bindgen] + pub async fn train_on_batch( + &mut self, + input: JsValue, + target: JsValue, + ) -> Result { + reset_scope_context(); + let _train_mode_guard = ModuleModeGuard::new(ModuleMode::Train); + // Convert input and target from JS arrays to Vec> + let input: Vec> = + serde_wasm_bindgen::from_value(input).map_err(|e| JsValue::from(e.to_string()))?; + let target: Vec> = + serde_wasm_bindgen::from_value(target).map_err(|e| JsValue::from(e.to_string()))?; + + if input.is_empty() || target.is_empty() { + return Err("Empty batch provided".into()); + }; + + let batch_size = input.len(); + let seq_len = input[0].len(); + if batch_size != target.len() + || input.iter().any(|x| x.len() != seq_len) + || target.iter().any(|x| x.len() != seq_len) + { + return Err("Inconsistent batch dimensions".into()); + } + + let (logits, attn_masks) = self.forward(input).await.map_err(|e| e.to_string())?; + + let target_flat: Vec = target.into_iter().flatten().collect(); + let target_tensor = Tensor::from_data( + target_flat, + shape![batch_size, seq_len], + self.device.clone(), + ); + + // Flatten the logits and targets, compute the cross-entropy loss with label smoothing + let logits_flat = logits.clone().flatten_to(1).map_err(|e| e.to_string())?; + let target_flat = target_tensor.flatten_to(1).map_err(|e| e.to_string())?; + let inp = log_softmax(logits_flat, 1).map_err(|e| e.to_string())?; + + let alpha = self.config.label_smoothing; + let loss = if alpha > 0.0 { + label_smoothed_nll(inp, target_flat, alpha).map_err(|e| e.to_string())? + } else { + nll_masked(inp, target_flat).map_err(|e| e.to_string())? + }; + + // We sum the loss outside of x entropy because we want to see per-token loss + let loss_summed = loss.clone().sum_all().map_err(|e| e.to_string())?; + + let grads = loss_summed.backward().map_err(|e| e.to_string())?; + + // Run an optimizer step (updating model parameters). + self.optimizer + .step(&grads, &self.device) + .await + .map_err(|e| e.to_string())?; + + // Transfer tensors to CPU + let loss_cpu = loss.to(&Device::CPU).await.map_err(|e| e.to_string())?; + let loss_vec = loss_cpu.to_vec::().await.map_err(|e| e.to_string())?; + + // Transfer attention masks to CPU and get their shape and flattened data + let attn_masks_cpu = attn_masks + .to(&Device::CPU) + .await + .map_err(|e| e.to_string())?; + let attn_masks_shape = attn_masks_cpu.shape().to_vec(); + let attn_masks_data = attn_masks_cpu + .to_vec::() + .await + .map_err(|e| e.to_string())?; + + // Add logits to the result: + let logits_cpu = logits.to(&Device::CPU).await.map_err(|e| e.to_string())?; + let logits_shape = logits_cpu.shape().to_vec(); + let logits_data = logits_cpu + .to_vec::() + .await + .map_err(|e| e.to_string())?; + + let result = serde_json::json!({ + "loss": { + "tokens": loss_vec, + "total": loss_vec.iter().sum::(), + }, + "learning_rate": self.optimizer.get_lr(), + "attn_masks": { + "data": attn_masks_data, + "shape": attn_masks_shape, + }, + "logits": { + "data": logits_data, + "shape": logits_shape, + } + }); + + serde_wasm_bindgen::to_value(&result).map_err(|e| e.to_string().into()) + } + + #[wasm_bindgen] + pub fn usage_bytes(&self) -> u64 { + self.device.try_gpu().unwrap().usage_bytes() + } + + #[wasm_bindgen] + pub fn webgpu_device(&self) -> Option { + self.device.try_gpu().unwrap().as_webgpu_device() + } + + #[wasm_bindgen] + pub async fn save_checkpoint(&self) -> Result { + self.varmap.download_url().await + } + + #[wasm_bindgen] + pub fn set_step_log_config(&mut self, config: JsValue) -> Result<(), JsValue> { + let config: JsStepLogConfig = + serde_wasm_bindgen::from_value(config).map_err(|e| JsValue::from(e.to_string()))?; + self.device + .try_gpu() + .unwrap() + .set_step_log_config(ratchet::StepLogConfig { + profiling: config.profiling, + debug_selection: match config.debug_selection { + Some(JsDebugSelection::String(s)) => match s.as_str() { + "all" => Some(ratchet::DebugSelection::All), + _ => None, + }, + Some(JsDebugSelection::Array(a)) => Some(ratchet::DebugSelection::Some(a)), + None => None, + }, + }); + Ok(()) + } + + #[wasm_bindgen] + pub fn take_step_log(&mut self) -> Option { + self.device.try_gpu().unwrap().take_step_log() + } + + #[wasm_bindgen] + pub async fn generate( + &mut self, + prompt: JsValue, + max_tokens: usize, + callback: Option, + ) -> Result { + // Convert prompt from JsValue -> Vec + let prompt_vec: Vec = + serde_wasm_bindgen::from_value(prompt).map_err(|e| JsValue::from(e.to_string()))?; + + // If a callback is provided, we do the streaming approach. + if let Some(callback_fn) = callback { + // Call existing GPT-2 generate with a streaming closure: + generate( + &mut self.model, + prompt_vec, + |tokens, logits_nd, attn_probs_data| { + // Convert the tokens to JS + let tokens_js = serde_wasm_bindgen::to_value(&tokens).unwrap_or(JsValue::NULL); + + // Convert the logits to a {shape, data} object + let shape = vec![ + logits_nd.shape()[0], + logits_nd.shape()[1], + logits_nd.shape()[2], + ]; + let data: Vec = logits_nd.into_iter().collect(); + + let logits_obj = js_sys::Object::new(); + let _ = js_sys::Reflect::set( + &logits_obj, + &JsValue::from_str("shape"), + &serde_wasm_bindgen::to_value(&shape).unwrap_or(JsValue::NULL), + ); + let _ = js_sys::Reflect::set( + &logits_obj, + &JsValue::from_str("data"), + &serde_wasm_bindgen::to_value(&data).unwrap_or(JsValue::NULL), + ); + + let attn_probs_obj = js_sys::Object::new(); + let _ = js_sys::Reflect::set( + &attn_probs_obj, + &JsValue::from_str("data"), + &serde_wasm_bindgen::to_value(&attn_probs_data).unwrap_or(JsValue::NULL), + ); + // Finally, call the JS callback with (tokens, logitsObj) + let _ = + callback_fn.call3(&JsValue::NULL, &tokens_js, &logits_obj, &attn_probs_obj); + }, + max_tokens, + ) + .await + .map_err(|e| JsValue::from(e.to_string()))?; + + // Return undefined if we're streaming via callback + Ok(JsValue::UNDEFINED) + } else { + // No callback was provided, so we accumulate only the final tokens/logits and return them. + let final_tokens: RefCell> = RefCell::new(Vec::new()); + let final_logits_data: RefCell> = RefCell::new(Vec::new()); + let final_logits_shape: RefCell> = RefCell::new(Vec::new()); + + let prompt_len = prompt_vec.len(); + + // We capture these as mut so we can overwrite them at each step with the latest pass + generate( + &mut self.model, + prompt_vec, + |tokens, logits_nd, _attn_probs_data| { + // Update tokens + final_tokens.borrow_mut().extend_from_slice(&tokens); + + // Convert the logits into shape/data only for the final pass + final_logits_shape.borrow_mut().extend_from_slice(&[ + logits_nd.shape()[0], + logits_nd.shape()[1], + logits_nd.shape()[2], + ]); + + final_logits_data.borrow_mut().extend(logits_nd.into_iter()); + + // Note that we don't bother passing along the attn_probs_data here. + // This is inconsistent but we'll deal with it if it becomes an issue. + }, + max_tokens, + ) + .await + .map_err(|e| JsValue::from(e.to_string()))?; + + let result = serde_json::json!({ + "tokens": final_tokens.borrow()[prompt_len..].to_vec(), + "logits": { + "shape": final_logits_shape.borrow().to_vec(), + "data": final_logits_data.borrow().to_vec(), + }, + }); + + Ok(serde_wasm_bindgen::to_value(&result).map_err(|e| e.to_string())?) + } + } +} + +/// A scheduler that does nothing, just passes through to the underlying optimizer. +/// This is used when no scheduler is selected. +pub struct NoopScheduler { + core: LRSchedulerCore, +} + +impl NoopScheduler { + pub fn new(optimizer: O) -> Self { + Self { + core: LRSchedulerCore::new(optimizer), + } + } +} + +impl LRScheduler for NoopScheduler { + fn optimizer_mut(&mut self) -> &mut O { + &mut self.core.optimizer + } + + fn base_lr(&self) -> f64 { + self.core.base_lr + } + + fn step_count(&self) -> usize { + self.core.step_count + } + + fn set_step_count(&mut self, count: usize) { + self.core.step_count = count; + } + + fn compute_lr(&self) -> f64 { + self.core.base_lr + } +} diff --git a/crates/ratchet-web-train/src/test_ops.rs b/crates/ratchet-web-train/src/test_ops.rs new file mode 100644 index 00000000..da20ef5e --- /dev/null +++ b/crates/ratchet-web-train/src/test_ops.rs @@ -0,0 +1,278 @@ +#[cfg(all(test, target_arch = "wasm32"))] +mod tests { + use ndarray::Array4; + use ratchet::{shape, DType, Device, Tensor}; + use serde::Deserialize; + use serde_json::Value; + use wasm_bindgen_test::*; + + use crate::test_utils::log_init; + + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + + const TEST_SUITE_JSON: &str = include_str!("../test_suite.json"); + + /// Represents a single test case in the JSON. + #[derive(Debug, Deserialize)] + struct TestCase { + // /// Human-readable name (e.g. "addition"). + // name: String, + /// The name of the operation (e.g. "add", "matmul", "conv2d", "relu", etc.). + operation: String, + /// Inputs are stored as arbitrary JSON. We'll parse them depending on the operation. + inputs: Value, + /// The expected output for this test. Also arbitrary JSON to parse as needed. + output: Value, + } + + /// Converts a nested JSON array of shape (m x n) into an `ndarray::Array2`. + fn json_to_array2_f32(value: &Value, device: &Device) -> Tensor { + // We expect a 2D list structure, e.g. [[0.1, 0.2], [0.3, 0.4]] + // Adjust the parsing logic if you have more dimensions or a different data shape. + let rows = value.as_array().expect("Expected outer array"); + + // Collect each row as a Vec + let row_vecs: Vec> = rows + .iter() + .map(|row| { + row.as_array() + .expect("Expected inner array") + .iter() + .map(|num| num.as_f64().expect("Expected a numeric value") as f32) + .collect() + }) + .collect(); + + // Get the shape + let nrows = row_vecs.len(); + let ncols = row_vecs[0].len(); // assume at least one row + + // Flatten the data + let flattened: Vec = row_vecs.into_iter().flatten().collect(); + + // Create tensor directly from data + Tensor::from_data(flattened, shape![nrows, ncols], device.clone()) + } + + /// Parse a 4D JSON array into an `Array4`. + /// Expects something like: + /// [ + /// [ + /// [ [0.1, 0.2], [0.3, 0.4] ], + /// [ [0.5, 0.6], [0.7, 0.8] ] + /// ], + /// [ + /// [ [1.1, 1.2], [1.3, 1.4] ], + /// [ [1.5, 1.6], [1.7, 1.8] ] + /// ] + /// ] + /// which corresponds to shape (batch_size, channels, height, width). + pub fn json_to_array4_f32(value: &Value) -> Array4 { + // Top-level array is "batch". + let batch = value + .as_array() + .expect("Expected top-level JSON array for 4D data."); + + // In many deep-learning use cases, the shape is [N, C, H, W]. + // We'll parse each dimension carefully. + // Collect all data in a flat Vec so we can feed it to `Array4::from_shape_vec`. + let mut data = Vec::new(); + let mut batch_size = 0_usize; + let mut channel_size = 0_usize; + let mut height_size = 0_usize; + let mut width_size = 0_usize; + + for channels in batch { + // Each "channels" is itself an array. + let channels_arr = channels + .as_array() + .expect("Expected array for the second dimension."); + + batch_size += 1; + // If we haven’t set channel_size yet, set it now. + if channel_size == 0 { + channel_size = channels_arr.len(); + } + + for height in channels_arr { + let height_arr = height + .as_array() + .expect("Expected array for the third dimension."); + if height_size == 0 { + height_size = height_arr.len(); + } + + for width in height_arr { + let width_arr = width + .as_array() + .expect("Expected array for the fourth dimension."); + if width_size == 0 { + width_size = width_arr.len(); + } + + // Finally, read numeric values. + for val in width_arr { + data.push(val.as_f64().expect("Expected float in JSON.") as f32); + } + } + } + } + + Array4::from_shape_vec((batch_size, channel_size, height_size, width_size), data) + .expect("Failed to create Array4 from parsed JSON data.") + } + + fn parse_scalar_f32(value: &Value) -> f32 { + value.as_f64().expect("Expected a JSON float for powf") as f32 + } + + async fn run_op_test_case(test_case: &TestCase, device: &Device) -> anyhow::Result<()> { + fn parse_inputs_2d( + inputs: &Value, + key1: &str, + key2: &str, + device: &Device, + ) -> (Tensor, Tensor) { + let arr1 = json_to_array2_f32(&inputs[key1], device); + let arr2 = json_to_array2_f32(&inputs[key2], device); + (arr1, arr2) + } + + let op = test_case.operation.as_str(); + log::info!("op = {:?}", op); + match op { + "add" => { + // Parse inputs + let (x, y) = parse_inputs_2d(&test_case.inputs, "x", "y", device); + // Parse expected output + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + // Perform operation + let result = (x + y).unwrap().to(&Device::CPU).await.unwrap(); + + // Compare + result.all_close(&expected, 1e-5, 1e-5)?; + } + + "matmul" => { + let (x, y) = parse_inputs_2d(&test_case.inputs, "x", "y", device); + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + let result = x.matmul(y, false, false)?.to(&Device::CPU).await?; + + result.all_close(&expected, 1e-5, 1e-5)?; + } + + "gather" => { + let (x, ids) = parse_inputs_2d(&test_case.inputs, "input", "index", device); + // Cast ids to i32 + let ids = ids.cast(DType::I32)?; + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + let result = x.gather(ids, 1)?.to(&Device::CPU).await?; + + result.all_close(&expected, 1e-5, 1e-5)?; + } + + "scatter_add" => { + let (x, ids) = parse_inputs_2d(&test_case.inputs, "input", "index", device); + // Cast ids to i32 + let ids = ids.cast(DType::I32)?; + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + let dst = Tensor::zeros::(x.shape(), device); + + let result = dst + .scatter_add(ids.clone(), x.clone(), 1)? + .to(&Device::CPU) + .await?; + + log::warn!("ids = {:?}", ids.to(&Device::CPU).await?); + log::warn!("result = {:?}", result); + log::warn!("expected = {:?}", expected); + log::warn!("x = {:?}", x.to(&Device::CPU).await?); + + result.all_close(&expected, 1e-5, 1e-5)?; + } + + "powf" => { + let x = json_to_array2_f32(&test_case.inputs["x"], device); + let y = parse_scalar_f32(&test_case.inputs["y"]); + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + let result = x.powf(y)?.to(&Device::CPU).await?; + + result.all_close(&expected, 1e-5, 1e-5)?; + } + + // "conv2d" => { + // // Example for 4D convolution data: parse (batch, in_channels, height, width) + // // plus kernel. Let’s assume your JSON structure is something like: + // // "inputs": { + // // "input": [[[...], [...], ... ], ... ], + // // "weight": [[[...], ...], ... ], + // // "stride": 1, + // // "padding": 0 + // // } + + // let input_4d = json_to_array4_f32(&test_case.inputs["input"]); + // let weight_4d = json_to_array4_f32(&test_case.inputs["weight"]); + // let stride = test_case.inputs["stride"].as_u64().unwrap() as usize; + // let padding = test_case.inputs["padding"].as_u64().unwrap() as usize; + + // let expected_4d = json_to_array4_f32(&test_case.output); + + // // (You’d implement conv2d in Rust or use a library—skipped for brevity.) + // let result_4d = rust_conv2d(&input_4d, &weight_4d, stride, padding); + + // // For 4D arrays, you'd have a compare function that handles 4D data + // compare_and_log_4d(&test_case.name, op, &result_4d, &expected_4d, 1e-5); + // } + "relu" => { + let x = json_to_array2_f32(&test_case.inputs, device); + let expected = json_to_array2_f32(&test_case.output, device) + .to(&Device::CPU) + .await?; + + let result = x.relu()?.to(&Device::CPU).await?; + + result.all_close(&expected, 1e-5, 1e-5)?; + } + _ => { + println!("Operation '{}' not yet implemented.", op); + } + } + + Ok(()) + } + + async fn run_test_cases(test_cases: &[TestCase]) -> anyhow::Result<()> { + let device = Device::request_device(ratchet::DeviceRequest::GPU) + .await + .unwrap(); + + for test_case in test_cases { + run_op_test_case(test_case, &device).await?; + } + Ok(()) + } + + #[wasm_bindgen_test] + async fn test_run_test_cases() { + log_init(); + log::error!("test_run_test_cases"); + let test_cases: Vec = serde_json::from_str(TEST_SUITE_JSON).unwrap(); + log::error!("test_run_test_cases 2"); + run_test_cases(&test_cases).await.unwrap(); + } +} diff --git a/crates/ratchet-web-train/src/test_utils.rs b/crates/ratchet-web-train/src/test_utils.rs new file mode 100644 index 00000000..7476f50d --- /dev/null +++ b/crates/ratchet-web-train/src/test_utils.rs @@ -0,0 +1,21 @@ +pub(crate) fn log_init() { + console_error_panic_hook::set_once(); + let logger = fern::Dispatch::new() + .format(|out, message, record| { + out.finish(format_args!( + "{}[{}][{}] {}", + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), + record.target(), + record.level(), + message + )) + }) + .level_for("tokenizers", log::LevelFilter::Off) + .level(log::LevelFilter::Info) + .chain(fern::Output::call(console_log::log)) + .apply(); + match logger { + Ok(_) => log::info!("Logging initialized."), + Err(error) => eprintln!("Error initializing logging: {:?}", error), + } +} diff --git a/crates/ratchet-web/.gitignore b/crates/ratchet-web/.gitignore deleted file mode 100644 index d53c04e7..00000000 --- a/crates/ratchet-web/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/test-data diff --git a/crates/ratchet-web/README.md b/crates/ratchet-web/README.md deleted file mode 100644 index a1247315..00000000 --- a/crates/ratchet-web/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# ratchet-web - diff --git a/crates/ratchet-web/src/db.rs b/crates/ratchet-web/src/db.rs deleted file mode 100644 index b7464268..00000000 --- a/crates/ratchet-web/src/db.rs +++ /dev/null @@ -1,286 +0,0 @@ -use indexed_db_futures::prelude::*; -use js_sys::Uint8Array; -use ratchet_loader::gguf::gguf::Header; -use ratchet_models::{ - registry::{AvailableModels, Quantization}, - TensorMap, WebTensor, -}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; -use wasm_bindgen::prelude::*; - -#[derive(Debug, thiserror::Error)] -pub enum RatchetDBError { - #[error("DomException {name} ({code}): {message}")] - DomException { - name: String, - message: String, - code: u16, - }, - #[error(transparent)] - SerdeError(#[from] serde_wasm_bindgen::Error), -} - -impl From for RatchetDBError { - fn from(e: indexed_db_futures::web_sys::DomException) -> Self { - Self::DomException { - name: e.name(), - message: e.message(), - code: e.code(), - } - } -} - -pub struct RatchetDB { - pub(crate) inner: IdbDatabase, -} - -type Result = std::result::Result; - -impl RatchetDB { - pub const DB_VERSION: u32 = 1; - pub const DB_NAME: &'static str = "ratchet"; - pub const MODEL_STORE: &'static str = "models"; - pub const TOKENIZER_STORE: &'static str = "tokenizers"; - pub const TENSOR_STORE: &'static str = "tensors"; - pub const TENSOR_INDEX: &'static str = "model_key"; - - fn serialize(o: &impl Serialize) -> Result { - serde_wasm_bindgen::to_value(o).map_err(|e| e.into()) - } - - fn deserialize Deserialize<'de>>(o: Option) -> Result> { - o.map(serde_wasm_bindgen::from_value) - .transpose() - .map_err(|e| e.into()) - } - - pub async fn open() -> Result { - let mut db_req: OpenDbRequest = IdbDatabase::open_u32(Self::DB_NAME, Self::DB_VERSION)?; - - db_req.set_on_upgrade_needed(Some(|evt: &IdbVersionChangeEvent| -> Result<(), JsValue> { - let create_store_if_needed = - |evt: &IdbVersionChangeEvent, store_key: &'static str| -> Result<(), JsValue> { - if let None = evt.db().object_store_names().find(|n| n == store_key) { - evt.db().create_object_store(store_key)?; - } - Ok(()) - }; - - let create_store_with_index_if_needed = |evt: &IdbVersionChangeEvent, - store_key: &'static str, - index_key: &'static str| - -> Result<(), JsValue> { - if let None = evt.db().object_store_names().find(|n| n == store_key) { - let store = evt.db().create_object_store(store_key)?; - store.create_index(index_key, &IdbKeyPath::str(index_key))?; - } - Ok(()) - }; - - create_store_if_needed(evt, Self::MODEL_STORE)?; - create_store_if_needed(evt, Self::TOKENIZER_STORE)?; - create_store_with_index_if_needed(evt, Self::TENSOR_STORE, Self::TENSOR_INDEX)?; - - Ok(()) - })); - - Ok(Self { - inner: db_req.await?, - }) - } - - pub async fn get_model(&self, key: &ModelKey) -> Result> { - let tx = self - .inner - .transaction_on_one_with_mode(Self::MODEL_STORE, IdbTransactionMode::Readonly)?; - let store = tx.object_store(Self::MODEL_STORE)?; - let serial_key = Self::serialize(key)?; - let req = store.get(&serial_key)?.await?; - Self::deserialize(req) - } - - pub async fn put_model(&self, key: &ModelKey, model: ModelRecord) -> Result<()> { - let tx = self - .inner - .transaction_on_one_with_mode(Self::MODEL_STORE, IdbTransactionMode::Readwrite)?; - let store = tx.object_store(Self::MODEL_STORE)?; - store - .put_key_val(&Self::serialize(key)?, &Self::serialize(&model)?)? - .await?; - Ok(()) - } - - pub async fn get_tensors(&self, key: &ModelKey) -> Result { - let tx = self - .inner - .transaction_on_one_with_mode(Self::MODEL_STORE, IdbTransactionMode::Readonly)?; - let store = tx.object_store(Self::MODEL_STORE)?; - let req = store.get(&Self::serialize(key)?)?.await?; - let model: ModelRecord = Self::deserialize(req)?.unwrap(); - - log::warn!("Model: {:?}", model); - let header = serde_wasm_bindgen::from_value::

(model.header).unwrap(); - - log::warn!("GOT HEADER: {:?}", header); - - let tx = self - .inner - .transaction_on_one_with_mode(Self::TENSOR_STORE, IdbTransactionMode::Readonly)?; - let store = tx.object_store(Self::TENSOR_STORE)?; - let index = store.index(Self::TENSOR_INDEX)?; - let matches = index.get_all_with_key(&Self::serialize(key)?)?.await?; - - let mut map = TensorMap::new(); - for record in matches { - let record: TensorRecord = Self::deserialize(Some(record))?.unwrap(); - let ti = header.tensor_infos.get(&record.name).unwrap(); - let tensor = WebTensor::new(ti.ggml_dtype, record.bytes, ti.shape.clone()); - map.insert(record.name, tensor); - } - Ok(map) - } - - pub async fn put_tensor(&self, tensor: TensorRecord) -> Result<()> { - let tx = self - .inner - .transaction_on_one_with_mode(Self::TENSOR_STORE, IdbTransactionMode::Readwrite)?; - let store = tx.object_store(Self::TENSOR_STORE)?; - store - .put_key_val( - &Self::serialize(&tensor.tensor_id)?, - &Self::serialize(&tensor)?, - )? - .await?; - Ok(()) - } - - pub async fn get_tokenizer>( - &self, - repo_id: S, - ) -> Result> { - let tx = self - .inner - .transaction_on_one_with_mode(Self::TOKENIZER_STORE, IdbTransactionMode::Readonly)?; - let store = tx.object_store(Self::TOKENIZER_STORE)?; - let req = store.get(&Self::serialize(&repo_id.as_ref())?)?.await?; - Self::deserialize(req) - } - - pub async fn put_tokenizer>( - &self, - repo_id: S, - tokenizer: TokenizerRecord, - ) -> Result<()> { - let tx = self - .inner - .transaction_on_one_with_mode(Self::TOKENIZER_STORE, IdbTransactionMode::Readwrite)?; - let store = tx.object_store(Self::TOKENIZER_STORE)?; - store - .put_key_val( - &Self::serialize(&repo_id.as_ref())?, - &Self::serialize(&tokenizer)?, - )? - .await?; - Ok(()) - } -} - -#[wasm_bindgen] -#[derive(Debug, Clone)] -pub struct ModelKey { - repo_id: String, - model_id: String, -} - -impl serde::Serialize for ModelKey { - fn serialize( - &self, - serializer: S, - ) -> std::result::Result { - let s = format!("{}:{}", self.repo_id, self.model_id); - serializer.serialize_str(&s) - } -} - -impl<'de> serde::Deserialize<'de> for ModelKey { - fn deserialize>( - deserializer: D, - ) -> std::result::Result { - let s = String::deserialize(deserializer)?; - let mut parts = s.split(':'); - let repo_id = parts.next().unwrap().to_string(); - let model_id = parts.next().unwrap().to_string(); - Ok(Self { repo_id, model_id }) - } -} - -impl ModelKey { - pub fn from_available(av: &AvailableModels, quant: Quantization) -> Self { - ModelKey { - repo_id: av.repo_id(), - model_id: av.model_id(quant), - } - } -} - -#[wasm_bindgen] -impl ModelKey { - #[wasm_bindgen(constructor)] - pub fn new(repo_id: String, model_id: String) -> Self { - Self { repo_id, model_id } - } - - #[wasm_bindgen(getter)] - pub fn repo_id(&self) -> String { - self.repo_id.clone() - } - - #[wasm_bindgen(getter)] - pub fn model_id(&self) -> String { - self.model_id.clone() - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ModelRecord { - pub key: ModelKey, - pub model: AvailableModels, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub header: JsValue, -} - -impl ModelRecord { - pub fn new(key: ModelKey, model: AvailableModels, header: Header) -> Self { - let header = serde_wasm_bindgen::to_value(&header).unwrap(); - Self { key, model, header } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TensorRecord { - pub tensor_id: Uuid, - pub name: String, - pub model_key: ModelKey, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub bytes: Uint8Array, -} - -impl TensorRecord { - pub fn new(name: String, model_key: ModelKey, bytes: Uint8Array) -> Self { - Self { - tensor_id: Uuid::new_v4(), - name, - model_key, - bytes, - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TokenizerRecord { - pub repo_id: String, - pub tokenizer_id: String, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub bytes: Uint8Array, -} diff --git a/crates/ratchet-web/src/lib.rs b/crates/ratchet-web/src/lib.rs deleted file mode 100644 index 66c6e4d9..00000000 --- a/crates/ratchet-web/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![cfg(target_arch = "wasm32")] -mod db; -mod model; diff --git a/crates/ratchet-web/src/model.rs b/crates/ratchet-web/src/model.rs deleted file mode 100644 index e08101f3..00000000 --- a/crates/ratchet-web/src/model.rs +++ /dev/null @@ -1,408 +0,0 @@ -use crate::db::*; -use futures::stream::TryStreamExt; -use futures::StreamExt; -use ratchet_hub::{Api, ApiBuilder, RepoType}; -use ratchet_loader::gguf::gguf::{self, Header, TensorInfo}; -use ratchet_models::moondream::{self, Moondream}; -use ratchet_models::phi2; -use ratchet_models::phi2::Phi2; -use ratchet_models::phi3::{self, Phi3}; -use ratchet_models::registry::{AvailableModels, PhiVariants, Quantization}; -use ratchet_models::whisper::{transcribe::transcribe, transcript::StreamedSegment, Whisper}; -use ratchet_models::TensorMap; -use tokenizers::Tokenizer; -use wasm_bindgen::prelude::*; - -#[derive(Debug)] -pub enum WebModel { - Whisper(Whisper), - Phi2(Phi2), - Phi3(Phi3), - Moondream(Moondream), -} - -impl WebModel { - pub async fn run(&mut self, input: JsValue) -> Result { - match self { - WebModel::Whisper(model) => { - let input: WhisperInputs = serde_wasm_bindgen::from_value(input)?; - let options = serde_wasm_bindgen::from_value(input.decode_options)?; - - let callback = if !input.callback.is_null() { - let rs_callback = |decoded: StreamedSegment| { - let js_decoded = serde_wasm_bindgen::to_value(&decoded).unwrap(); - let _ = input.callback.call1(&JsValue::NULL, &js_decoded); - }; - Some(rs_callback) - } else { - None - }; - - let result = transcribe(model, input.audio, options, callback) - .await - .unwrap(); - serde_wasm_bindgen::to_value(&result).map_err(|e| e.into()) - } - WebModel::Phi2(model) => { - let input: PhiInputs = serde_wasm_bindgen::from_value(input)?; - let rs_callback = |output: String| { - let _ = input.callback.call1(&JsValue::NULL, &output.into()); - }; - let prompt = input.prompt; - - let model_repo = ApiBuilder::from_hf("microsoft/phi-2", RepoType::Model).build(); - let model_bytes = model_repo.get("tokenizer.json").await?; - let tokenizer = Tokenizer::from_bytes(model_bytes.to_vec()).unwrap(); - phi2::generate(model, tokenizer, prompt, rs_callback) - .await - .unwrap(); - Ok(JsValue::NULL) - } - WebModel::Phi3(model) => { - let input: PhiInputs = serde_wasm_bindgen::from_value(input)?; - let rs_callback = |output: String| { - let _ = input.callback.call1(&JsValue::NULL, &output.into()); - }; - let prompt = input.prompt; - - let model_repo = - ApiBuilder::from_hf("microsoft/Phi-3-mini-4k-instruct", RepoType::Model) - .build(); - let model_bytes = model_repo.get("tokenizer.json").await?; - let tokenizer = Tokenizer::from_bytes(model_bytes.to_vec()).unwrap(); - phi3::generate(model, tokenizer, prompt, rs_callback) - .await - .unwrap(); - Ok(JsValue::NULL) - } - WebModel::Moondream(model) => { - let input: MoondreamInputs = serde_wasm_bindgen::from_value(input)?; - let rs_callback = |output: String| { - let _ = input.callback.call1(&JsValue::NULL, &output.into()); - }; - let model_repo = - ApiBuilder::from_hf("tgestson/ratchet-moondream2", RepoType::Model).build(); - let model_bytes = model_repo.get("tokenizer.json").await?; - let tokenizer = Tokenizer::from_bytes(model_bytes.to_vec()).unwrap(); - moondream::generate( - model, - input.image_bytes, - input.question, - tokenizer, - rs_callback, - ) - .await - .unwrap(); - Ok(JsValue::NULL) - } - } - } - - pub async fn from_stored( - model_record: ModelRecord, - tensor_map: TensorMap, - ) -> Result { - let header = serde_wasm_bindgen::from_value::
(model_record.header).unwrap(); - match model_record.model { - AvailableModels::Whisper(variant) => { - let model = Whisper::from_web(header, tensor_map, variant).await?; - Ok(WebModel::Whisper(model)) - } - AvailableModels::Phi(variant) => match variant { - PhiVariants::Phi2 => { - let model = Phi2::from_web(header, tensor_map).await?; - Ok(WebModel::Phi2(model)) - } - PhiVariants::Phi3 => { - let model = Phi3::from_web(header, tensor_map).await?; - Ok(WebModel::Phi3(model)) - } - }, - AvailableModels::Moondream => { - let model = Moondream::from_web(header, tensor_map).await?; - Ok(WebModel::Moondream(model)) - } - _ => Err(anyhow::anyhow!("Unknown model type")), - } - } -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct WhisperInputs { - pub audio: Vec, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub decode_options: JsValue, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub callback: js_sys::Function, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct PhiInputs { - pub prompt: String, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub callback: js_sys::Function, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct MoondreamInputs { - pub question: String, - pub image_bytes: Vec, - #[serde(with = "serde_wasm_bindgen::preserve")] - pub callback: js_sys::Function, -} - -#[wasm_bindgen] -#[derive(Debug)] -pub struct Model { - inner: WebModel, -} - -#[wasm_bindgen] -impl Model { - /// The main JS entrypoint into the library. - /// - /// Loads a model with the provided ID. - /// This key should be an enum of supported models. - #[wasm_bindgen] - pub async fn load( - model: AvailableModels, - quantization: Quantization, - progress: &js_sys::Function, - ) -> Result { - let model_key = ModelKey::from_available(&model, quantization); - let model_repo = ApiBuilder::from_hf(&model_key.repo_id(), RepoType::Model).build(); - - let webModel = Self::load_inner(model, &model_repo, model_key, progress).await?; - - Ok(Model { inner: webModel }) - } - - #[wasm_bindgen] - pub async fn load_custom( - endpoint: String, - model: AvailableModels, - quantization: Quantization, - progress: &js_sys::Function, - ) -> Result { - let model_key = ModelKey::from_available(&model, quantization); - let model_repo = ApiBuilder::from_custom(endpoint).build(); - - let webModel = Self::load_inner(model, &model_repo, model_key, progress).await?; - - Ok(Model { inner: webModel }) - } - - async fn load_inner( - model: AvailableModels, - model_repo: &Api, - model_key: ModelKey, - progress: &js_sys::Function, - ) -> Result { - let db = RatchetDB::open().await.map_err(|e| { - let e: JsError = e.into(); - Into::::into(e) - })?; - - log::warn!("Loading model: {:?}", model_key); - if let None = db.get_model(&model_key).await.map_err(|e| { - let e: JsError = e.into(); - Into::::into(e) - })? { - let header: gguf::Header = serde_wasm_bindgen::from_value( - model_repo.fetch_gguf_header(&model_key.model_id()).await?, - )?; - Self::fetch_tensors(&db, &model_repo, &header, model_key.clone(), progress).await?; - let model_record = ModelRecord::new(model_key.clone(), model.clone(), header); - db.put_model(&model_key, model_record).await.map_err(|e| { - let e: JsError = e.into(); - Into::::into(e) - })?; - }; - - let model_record = db.get_model(&model_key).await.unwrap().unwrap(); - let tensors = db.get_tensors(&model_key).await.unwrap(); - - Ok(WebModel::from_stored(model_record, tensors).await.unwrap()) - } - - /// User-facing method to run the model. - /// - /// Untyped input is required unfortunately. - pub async fn run(&mut self, input: JsValue) -> Result { - self.inner.run(input).await - } - - async fn fetch_tensors( - db: &RatchetDB, - model_repo: &Api, - header: &Header, - model_key: ModelKey, - progress: &js_sys::Function, - ) -> Result<(), JsValue> { - let model_id = model_key.model_id(); - let data_offset = header.tensor_data_offset; - let content_len = header - .tensor_infos - .values() - .fold(0, |acc, ti| acc + ti.size_in_bytes()); - - let mut tensor_infos: Vec<(String, TensorInfo)> = - header.tensor_infos.clone().into_iter().collect(); - tensor_infos.sort_by(|(_, a), (_, b)| b.size_in_bytes().cmp(&a.size_in_bytes())); - - let tensor_stream = futures::stream::iter(tensor_infos); - - let mut total_progress = 0.0; - - tensor_stream - .map(|(name, info): (String, TensorInfo)| { - let model_id = model_id.clone(); - let model_key = model_key.clone(); - async move { - let range = info.byte_range(data_offset); - let bytes = model_repo - .fetch_range(&model_id, range.start, range.end) - .await - .unwrap(); - let length = bytes.length(); - let record = - TensorRecord::new(name.clone().to_string(), model_key.clone(), bytes); - db.put_tensor(record).await.map_err(|e| { - let e: JsError = e.into(); - Into::::into(e) - }); - length - } - }) - .buffer_unordered(6) - .map(|num_bytes| { - let req_progress = (num_bytes as f64) / (content_len as f64) * 100.0; - total_progress += req_progress; - let _ = progress.call1(&JsValue::NULL, &total_progress.into()); - }) - .collect::<()>() - .await; - - Ok(()) - } -} - -#[cfg(all(test, target_arch = "wasm32"))] -mod tests { - use super::*; - use ratchet_hub::{ApiBuilder, RepoType}; - use ratchet_models::registry::PhiVariants; - use ratchet_models::registry::WhisperVariants; - use ratchet_models::whisper::options::DecodingOptionsBuilder; - use tokenizers::Tokenizer; - use wasm_bindgen_test::*; - - wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); - - fn log_init() { - console_error_panic_hook::set_once(); - let logger = fern::Dispatch::new() - .format(|out, message, record| { - out.finish(format_args!( - "{}[{}][{}] {}", - chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), - record.target(), - record.level(), - message - )) - }) - .level_for("tokenizers", log::LevelFilter::Off) - .level(log::LevelFilter::Warn) - .chain(fern::Output::call(console_log::log)) - .apply(); - match logger { - Ok(_) => log::info!("Logging initialized."), - Err(error) => eprintln!("Error initializing logging: {:?}", error), - } - } - - fn load_sample(bytes: &[u8]) -> Vec { - let mut reader = hound::WavReader::new(std::io::Cursor::new(bytes)).unwrap(); - reader - .samples::() - .map(|x| x.unwrap() as f32 / 32768.0) - .collect::>() - } - - #[wasm_bindgen_test] - async fn whisper_browser() -> Result<(), JsValue> { - log_init(); - let download_cb: Closure = Closure::new(|p| { - log::info!("Provided closure got progress: {}", p); - }); - let js_cb: &js_sys::Function = download_cb.as_ref().unchecked_ref(); - - let mut model = Model::load( - AvailableModels::Whisper(WhisperVariants::Base), - Quantization::F16, - js_cb, - ) - .await - .unwrap(); - - let data_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let audio_bytes = data_repo.get("mm0.wav").await?; - let sample = load_sample(&audio_bytes.to_vec()); - - let decode_options = DecodingOptionsBuilder::default().build(); - - let cb: Closure = Closure::new(|s| { - log::info!("GENERATED SEGMENT: {:?}", s); - }); - let js_cb: &js_sys::Function = cb.as_ref().unchecked_ref(); - - let input = WhisperInputs { - audio: sample, - decode_options, - callback: js_cb.clone(), - }; - let input = serde_wasm_bindgen::to_value(&input).unwrap(); - let result = model.run(input).await.unwrap(); - log::warn!("Result: {:?}", result); - Ok(()) - } - - #[wasm_bindgen_test] - async fn whisper_browser_custom() -> Result<(), JsValue> { - log_init(); - let download_cb: Closure = Closure::new(|p| { - log::info!("Provided closure got progress: {}", p); - }); - let js_cb: &js_sys::Function = download_cb.as_ref().unchecked_ref(); - - let mut model = Model::load_custom( - "https://huggingface.co/FL33TW00D-HF/whisper-base/resolve/main".to_string(), - AvailableModels::Whisper(WhisperVariants::Base), - Quantization::F16, - js_cb, - ) - .await - .unwrap(); - - let data_repo = ApiBuilder::from_hf("FL33TW00D-HF/ratchet-util", RepoType::Dataset).build(); - let audio_bytes = data_repo.get("mm0.wav").await?; - let sample = load_sample(&audio_bytes.to_vec()); - - let decode_options = DecodingOptionsBuilder::default().build(); - - let cb: Closure = Closure::new(|s| { - log::info!("GENERATED SEGMENT: {:?}", s); - }); - let js_cb: &js_sys::Function = cb.as_ref().unchecked_ref(); - - let input = WhisperInputs { - audio: sample, - decode_options, - callback: js_cb.clone(), - }; - let input = serde_wasm_bindgen::to_value(&input).unwrap(); - let result = model.run(input).await.unwrap(); - log::warn!("Result: {:?}", result); - Ok(()) - } -} diff --git a/examples/ratchet-moondream/.gitignore b/examples/ratchet-moondream/.gitignore deleted file mode 100644 index 4d29575d..00000000 --- a/examples/ratchet-moondream/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/examples/ratchet-moondream/README.md b/examples/ratchet-moondream/README.md deleted file mode 100644 index 5e7cf25e..00000000 --- a/examples/ratchet-moondream/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `npm start` - -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. - -The page will reload when you make changes.\ -You may also see any lint errors in the console. - -### `npm test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `npm run build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. diff --git a/examples/ratchet-moondream/package-lock.json b/examples/ratchet-moondream/package-lock.json deleted file mode 100644 index 06febf98..00000000 --- a/examples/ratchet-moondream/package-lock.json +++ /dev/null @@ -1,18080 +0,0 @@ -{ - "name": "ratchet-moondream", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ratchet-moondream", - "version": "0.1.0", - "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.19", - "@mui/material": "^5.15.19", - "@ratchet-ml/ratchet-web": "file:../../target/pkg/ratchet-web", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-scripts": "5.0.1", - "web-vitals": "^2.1.4" - }, - "devDependencies": { - "prettier": "3.3.1" - } - }, - "../../target/pkg/ratchet-web": { - "name": "@ratchet/ratchet-web", - "version": "0.3.0", - "license": "MIT" - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/eslint-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", - "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/eslint-parser/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", - "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", - "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-decorators": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", - "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", - "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", - "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-flow": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", - "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", - "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.24.7", - "@babel/plugin-transform-react-jsx-development": "^7.24.7", - "@babel/plugin-transform-react-pure-annotations": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "node_modules/@csstools/normalize.css": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", - "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==" - }, - "node_modules/@csstools/postcss-cascade-layers": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", - "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.2", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-color-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", - "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", - "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-hwb-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", - "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-ic-unit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", - "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", - "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-nested-calc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", - "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-normalize-display-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", - "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-oklab-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", - "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", - "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", - "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", - "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", - "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-unset-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", - "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.10" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", - "dependencies": { - "@emotion/memoize": "^0.8.1" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" - }, - "node_modules/@emotion/react": { - "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", - "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", - "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" - }, - "node_modules/@emotion/styled": { - "version": "11.11.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", - "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/is-prop-valid": "^1.2.2", - "@emotion/serialize": "^1.1.4", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz", - "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==", - "dependencies": { - "@floating-ui/utils": "^0.2.0" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", - "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", - "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", - "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", - "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", - "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@floating-ui/react-dom": "^2.0.8", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.19", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.19.tgz", - "integrity": "sha512-tCHSi/Tomez9ERynFhZRvFO6n9ATyrPs+2N80DMDzp6xDVirbBjEwhPcE+x7Lj+nwYw0SqFkOxyvMP0irnm55w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mui/icons-material": { - "version": "5.15.19", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.19.tgz", - "integrity": "sha512-RsEiRxA5azN9b8gI7JRqekkgvxQUlitoBOtZglflb8cUDyP12/cP4gRwhb44Ea1/zwwGGjAj66ZJpGHhKfibNA==", - "dependencies": { - "@babel/runtime": "^7.23.9" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material": { - "version": "5.15.19", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.19.tgz", - "integrity": "sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/core-downloads-tracker": "^5.15.19", - "@mui/system": "^5.15.15", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^18.2.0", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@mui/private-theming": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", - "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.15.14", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/styled-engine": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", - "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/system": { - "version": "5.15.15", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.15.tgz", - "integrity": "sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.15.14", - "@mui/styled-engine": "^5.15.14", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/types": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", - "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", - "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.11", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dependencies": { - "eslint-scope": "5.1.1" - } - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", - "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", - "dependencies": { - "ansi-html": "^0.0.9", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^4.2.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x || 5.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@ratchet-ml/ratchet-web": { - "resolved": "../../target/pkg/ratchet-web", - "link": true - }, - "node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", - "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", - "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", - "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", - "dependencies": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", - "dependencies": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "dependencies": { - "@babel/types": "^7.12.6" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", - "dependencies": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", - "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/node": { - "version": "20.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", - "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "16.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", - "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", - "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", - "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", - "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", - "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-plugin-named-asset-import": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "peerDependencies": { - "@babel/core": "^7.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-react-app": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", - "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/bfj": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", - "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", - "dependencies": { - "bluebird": "^3.7.2", - "check-types": "^11.2.3", - "hoopy": "^0.1.4", - "jsonpath": "^1.1.1", - "tryer": "^1.0.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001629", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001629.tgz", - "integrity": "sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/check-types": { - "version": "11.2.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", - "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==" - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/css-blank-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", - "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-blank-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-has-pseudo": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", - "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-has-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "dependencies": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "bin": { - "css-prefers-color-scheme": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssdb": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", - "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ] - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "deprecated": "Use your platform's native DOMException instead", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.794", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.794.tgz", - "integrity": "sha512-6FApLtsYhDCY0Vglq3AptsdxQ+PJLc6AxlAM0HjEihUAiOPPbkASEsq9gtxUeZY9o0sJIEa3WnF0vVH4VT4iug==" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==" - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-react-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", - "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-flowtype": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", - "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", - "dependencies": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@babel/plugin-syntax-flow": "^7.14.5", - "@babel/plugin-transform-react-jsx": "^7.14.9", - "eslint": "^8.1.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "25.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", - "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", - "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", - "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.34.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", - "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.8", - "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", - "object.values": "^1.2.0", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-testing-library": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", - "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", - "dependencies": { - "@typescript-eslint/utils": "^5.58.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", - "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", - "dependencies": { - "harmony-reflect": "^1.4.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", - "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" - } - }, - "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jake": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", - "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jake/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", - "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", - "dependencies": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^28.0.0", - "jest-watcher": "^28.0.0", - "slash": "^4.0.0", - "string-length": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "jest": "^27.0.0 || ^28.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-watch-typeahead/node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", - "dependencies": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/jest-watch-typeahead/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", - "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", - "dependencies": { - "char-regex": "^2.0.0", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", - "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.3.tgz", - "integrity": "sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", - "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" - } - }, - "node_modules/jsonpath/node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", - "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", - "dependencies": { - "array.prototype.reduce": "^1.0.6", - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "gopd": "^1.0.1", - "safe-array-concat": "^1.1.2" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", - "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-browser-comments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "browserslist": ">=4", - "postcss": ">=8" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=7.6.0" - }, - "peerDependencies": { - "postcss": "^8.4.6" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", - "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", - "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", - "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-custom-media": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", - "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-custom-properties": { - "version": "12.1.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", - "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", - "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", - "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", - "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-env-function": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", - "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-flexbugs-fixes": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "peerDependencies": { - "postcss": "^8.1.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", - "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-image-set-function": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", - "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-initial": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-lab-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", - "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.3.tgz", - "integrity": "sha512-sntgmxj8o7DE7g/Qi60cqpLBA3HG3STcDA0kO+WfB05jEKhZMbY7umNm2rBpQvsmZ16/lPXCJGW2672dgOUkrg==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/postcss-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", - "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-logical": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-media-minmax": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nesting": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", - "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-normalize": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", - "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", - "dependencies": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "browserslist": ">= 4", - "postcss": ">= 8" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-opacity-percentage": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", - "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", - "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", - "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", - "dependencies": { - "@csstools/postcss-cascade-layers": "^1.1.1", - "@csstools/postcss-color-function": "^1.1.1", - "@csstools/postcss-font-format-keywords": "^1.0.1", - "@csstools/postcss-hwb-function": "^1.0.2", - "@csstools/postcss-ic-unit": "^1.0.1", - "@csstools/postcss-is-pseudo-class": "^2.0.7", - "@csstools/postcss-nested-calc": "^1.0.0", - "@csstools/postcss-normalize-display-values": "^1.0.1", - "@csstools/postcss-oklab-function": "^1.1.1", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.1", - "@csstools/postcss-text-decoration-shorthand": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.2", - "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.4", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.1.0", - "postcss-attribute-case-insensitive": "^5.0.2", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.4", - "postcss-color-hex-alpha": "^8.0.4", - "postcss-color-rebeccapurple": "^7.1.1", - "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.10", - "postcss-custom-selectors": "^6.0.3", - "postcss-dir-pseudo-class": "^6.0.5", - "postcss-double-position-gradients": "^3.1.2", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.5", - "postcss-image-set-function": "^4.0.7", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.1", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.2.0", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.4", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.5", - "postcss-pseudo-class-any-link": "^7.1.6", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", - "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "peerDependencies": { - "postcss": "^8.0.3" - } - }, - "node_modules/postcss-selector-not": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", - "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz", - "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-app-polyfill": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", - "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", - "dependencies": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-dev-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-scripts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", - "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", - "dependencies": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" - }, - "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - }, - "peerDependencies": { - "react": ">= 16", - "typescript": "^3.2.1 || ^4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", - "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", - "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^7.0.35", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=8.9" - }, - "peerDependencies": { - "rework": "1.0.1", - "rework-visit": "1.0.0" - }, - "peerDependenciesMeta": { - "rework": { - "optional": true - }, - "rework-visit": { - "optional": true - } - } - }, - "node_modules/resolve-url-loader/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/resolve-url-loader/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/resolve-url-loader/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sanitize.css": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", - "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" - }, - "node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", - "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", - "dependencies": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", - "dependencies": { - "escodegen": "^1.8.1" - } - }, - "node_modules/static-eval/node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/static-eval/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/static-eval/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-eval/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-eval/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", - "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/svgo/node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/svgo/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/tailwindcss": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", - "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dependencies": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-vitals": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-manifest-plugin": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", - "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", - "dependencies": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "peerDependencies": { - "webpack": "^4.44.2 || ^5.47.0" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", - "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", - "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", - "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-background-sync": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", - "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", - "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-build": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", - "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", - "dependencies": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.6.0", - "workbox-broadcast-update": "6.6.0", - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-google-analytics": "6.6.0", - "workbox-navigation-preload": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-range-requests": "6.6.0", - "workbox-recipes": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0", - "workbox-streams": "6.6.0", - "workbox-sw": "6.6.0", - "workbox-window": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", - "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", - "dependencies": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, - "node_modules/workbox-build/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/workbox-build/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/workbox-build/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/workbox-build/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/workbox-build/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "node_modules/workbox-build/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", - "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", - "deprecated": "workbox-background-sync@6.6.0", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", - "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" - }, - "node_modules/workbox-expiration": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", - "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-google-analytics": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", - "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", - "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", - "dependencies": { - "workbox-background-sync": "6.6.0", - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", - "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-precaching": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", - "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-range-requests": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", - "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-recipes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", - "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", - "dependencies": { - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-routing": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", - "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-strategies": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", - "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-streams": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", - "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0" - } - }, - "node_modules/workbox-sw": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", - "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" - }, - "node_modules/workbox-webpack-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", - "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", - "dependencies": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.9.0" - } - }, - "node_modules/workbox-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/workbox-window": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", - "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", - "dependencies": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.6.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/examples/ratchet-moondream/package.json b/examples/ratchet-moondream/package.json deleted file mode 100644 index 2192cb8d..00000000 --- a/examples/ratchet-moondream/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "ratchet-moondream", - "version": "0.1.0", - "private": true, - "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.19", - "@mui/material": "^5.15.19", - "@ratchet-ml/ratchet-web": "file:../../target/pkg/ratchet-web", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-scripts": "5.0.1", - "web-vitals": "^2.1.4" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "devDependencies": { - "prettier": "3.3.1" - } -} diff --git a/examples/ratchet-moondream/public/index.html b/examples/ratchet-moondream/public/index.html deleted file mode 100644 index 5d1e5bc2..00000000 --- a/examples/ratchet-moondream/public/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - Ratchet Moondream - - - -
- - - diff --git a/examples/ratchet-moondream/public/manifest.json b/examples/ratchet-moondream/public/manifest.json deleted file mode 100644 index 080d6c77..00000000 --- a/examples/ratchet-moondream/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/examples/ratchet-moondream/public/robots.txt b/examples/ratchet-moondream/public/robots.txt deleted file mode 100644 index e9e57dc4..00000000 --- a/examples/ratchet-moondream/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/examples/ratchet-moondream/src/App.css b/examples/ratchet-moondream/src/App.css deleted file mode 100644 index 74b5e053..00000000 --- a/examples/ratchet-moondream/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/examples/ratchet-moondream/src/App.js b/examples/ratchet-moondream/src/App.js deleted file mode 100644 index 340e48be..00000000 --- a/examples/ratchet-moondream/src/App.js +++ /dev/null @@ -1,242 +0,0 @@ -import "./App.css"; -import { Model, Quantization, default as init } from "@ratchet-ml/ratchet-web"; -import { styled } from "@mui/material/styles"; -import { useState, useEffect } from "react"; -import { - LinearProgress, - TextField, - Button, - Container, - Card, - CardMedia, - Stack, - Box, - Dialog, - DialogActions, - DialogContentText, - DialogTitle, - DialogContent, - Typography, - CardActions, - InputAdornment, - IconButton, -} from "@mui/material"; -import SendIcon from "@mui/icons-material/Send"; - -const VisuallyHiddenInput = styled("input")({ - clip: "rect(0 0 0 0)", - clipPath: "inset(50%)", - height: 1, - overflow: "hidden", - position: "absolute", - bottom: 0, - left: 0, - whiteSpace: "nowrap", - width: 1, -}); - -function App() { - const [question, setQuestion] = useState(""); - const [generatedText, setGeneratedText] = useState(""); - const [image, setImage] = useState(new Uint8Array()); - const [progress, setProgress] = useState(0); - const [isLoading, setIsLoading] = useState(true); - const [accepted, setAccepted] = useState(false); - const [isSupportedBrowser, setIsSupportedBrowser] = useState(true); - const [ratchetDBExists, setRatchetDBExists] = useState(false); - const [model, setModel] = useState(null); - const [isRunning, setIsRunning] = useState(false); - - useEffect(() => { - (async () => { - await init(); - setRatchetDBExists( - (await window.indexedDB.databases()) - .map((db) => db.name) - .includes("ratchet"), - ); - await setImage( - new Uint8Array( - await ( - await fetch( - "https://raw.githubusercontent.com/vikhyat/moondream/main/assets/demo-1.jpg", - ) - ).arrayBuffer(), - ), - ); - })(); - }, []); - - async function loadModel() { - setAccepted(true); - setProgress(2); - setModel( - await Model.load("Moondream", Quantization.Q8_0, (p) => setProgress(p)), - ); - setProgress(100); - setIsLoading(false); - } - - async function runModel() { - if (!model || isRunning) { - return; - } - - setGeneratedText(""); - - let cb = (s) => { - setGeneratedText((prevText) => { - return prevText + s; - }); - }; - - setIsRunning(true); - await model.run({ question: question, image_bytes: image, callback: cb }); - setIsRunning(false); - } - - async function handleUpload(e) { - if (e.target.files.length == 0) { - return; - } - setImage(new Uint8Array(await e.target.files[0].arrayBuffer())); - } - - async function keypress(e) { - if (e.key === "Enter") { - runModel(); - e.preventDefault(); - } - } - - async function deleteWeights() { - setAccepted(false); - setProgress(0); - setModel(null); - await window.indexedDB.deleteDatabase("ratchet"); - setIsLoading(true); - } - - return ( -
- - - - {navigator.gpu ? "Load Model" : "Unsupported Browser"} - - - - {navigator.gpu - ? "This app requires downloading a 2.2GB model which may take a few minutes. If the model has been previously downloaded, it will be loaded from cache." - : "This app requires a browser that supports webgpu"} - - - {navigator.gpu ? ( - - - - ) : ( - <> - )} - - - - - Moondream by{" "} - Vikhyat running - on WebGpu via{" "} - Ratchet - - - - - - - - - - - - - setQuestion(e.target.value)} - onKeyDown={keypress} - InputProps={{ - endAdornment: ( - - - - - - ), - }} - /> - -
- -
- {isLoading && progress < 99 ? ( - - Downloading Weights... - - ) : ( - <> - )} - {isLoading && progress > 99 ? ( - - Preparing Weights... - - ) : ( - <> - )} -
- {generatedText} -
-
-
-
- ); -} - -export default App; diff --git a/examples/ratchet-moondream/src/index.css b/examples/ratchet-moondream/src/index.css deleted file mode 100644 index 4a1df4db..00000000 --- a/examples/ratchet-moondream/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} diff --git a/examples/ratchet-moondream/src/index.js b/examples/ratchet-moondream/src/index.js deleted file mode 100644 index df868170..00000000 --- a/examples/ratchet-moondream/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import "./index.css"; -import App from "./App"; - -const root = ReactDOM.createRoot(document.getElementById("root")); -root.render( - - - , -); diff --git a/examples/ratchet-phi/.gitignore b/examples/ratchet-phi/.gitignore deleted file mode 100644 index fd3dbb57..00000000 --- a/examples/ratchet-phi/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/examples/ratchet-phi/README.md b/examples/ratchet-phi/README.md deleted file mode 100644 index c4033664..00000000 --- a/examples/ratchet-phi/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/examples/ratchet-phi/next.config.mjs b/examples/ratchet-phi/next.config.mjs deleted file mode 100644 index 15eff7c7..00000000 --- a/examples/ratchet-phi/next.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - output: 'export' -}; - -export default nextConfig; diff --git a/examples/ratchet-phi/package.json b/examples/ratchet-phi/package.json deleted file mode 100644 index 2be8c174..00000000 --- a/examples/ratchet-phi/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "ratchet-phi", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@ffmpeg/ffmpeg": "0.12.6", - "@ffmpeg/util": "^0.12.1", - "@ratchet-ml/ratchet-web": "link:../../target/pkg/ratchet-web", - "fix-webm-duration": "^1.0.5", - "next": "14.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-hot-toast": "^2.4.1", - "react-responsive-modal": "^6.4.2" - }, - "devDependencies": { - "@types/node": "^20.11.24", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", - "autoprefixer": "^10.4.18", - "postcss": "^8.4.35", - "tailwindcss": "^3.4.1", - "typescript": "^5.3.3" - } -} diff --git a/examples/ratchet-phi/postcss.config.js b/examples/ratchet-phi/postcss.config.js deleted file mode 100644 index 33ad091d..00000000 --- a/examples/ratchet-phi/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/examples/ratchet-phi/src/app/components/WebGPUModal.tsx b/examples/ratchet-phi/src/app/components/WebGPUModal.tsx deleted file mode 100644 index 91ff1134..00000000 --- a/examples/ratchet-phi/src/app/components/WebGPUModal.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useState, useEffect } from "react"; -import Modal from "react-responsive-modal"; - -const WebGPUModal = () => { - const [hasWebGPU, setHasWebGPU] = useState(false); - const [isModalOpen, setIsModalOpen] = useState(false); - - useEffect(() => { - //@ts-ignore - if (!navigator.gpu) { - setIsModalOpen(true); - return; - } - setHasWebGPU(true); - }, []); - - const handleModalClose = () => { - setIsModalOpen(false); - }; - - const closeIcon = ( - - - - - - - - - - - - - - - - - - ); - - return ( - <> - {!hasWebGPU ? ( - -
-
-

- Uh oh! It looks like your browser doesn't - support WebGPU. Please try again in supported browser (Chrome 121+). -

-
-
-
- ) : ( - <> - )} - - ); -}; - -export default WebGPUModal; - diff --git a/examples/ratchet-phi/src/app/components/progressBar.tsx b/examples/ratchet-phi/src/app/components/progressBar.tsx deleted file mode 100644 index 732d98fc..00000000 --- a/examples/ratchet-phi/src/app/components/progressBar.tsx +++ /dev/null @@ -1,19 +0,0 @@ -const ProgressBar = ({ progress }: any) => { - return ( - <> - {progress > 0 && progress < 100 && ( -
-
-
-
-
- )} - - ); -}; - -export default ProgressBar; - diff --git a/examples/ratchet-phi/src/app/components/warningModal.tsx b/examples/ratchet-phi/src/app/components/warningModal.tsx deleted file mode 100644 index 37e93d74..00000000 --- a/examples/ratchet-phi/src/app/components/warningModal.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from "react"; -import Modal from "react-responsive-modal"; - -interface WarningModalProps { - isModalOpen: boolean; - setIsModalOpen: (value: boolean) => void; - loadModel: () => void; -} - -const WarningModal = ({ isModalOpen, setIsModalOpen, loadModel }: WarningModalProps) => { - const handleModalClose = () => { - setIsModalOpen(false); - }; - - const closeIcon = ( - - - - - - - - - - - - - - - - - - ); - - return ( - <> - {isModalOpen ? ( - -
-
-

- ⚠️ You are about to download a 2.9GB file. Click to confirm. -

- -
-
-
- ) : ( - <> - )} - - ); -}; - -export default WarningModal; - diff --git a/examples/ratchet-phi/src/app/favicon.ico b/examples/ratchet-phi/src/app/favicon.ico deleted file mode 100644 index 718d6fea..00000000 Binary files a/examples/ratchet-phi/src/app/favicon.ico and /dev/null differ diff --git a/examples/ratchet-phi/src/app/globals.css b/examples/ratchet-phi/src/app/globals.css deleted file mode 100644 index f3990aba..00000000 --- a/examples/ratchet-phi/src/app/globals.css +++ /dev/null @@ -1,344 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -.loader { - animation: spin 1s linear infinite; - height: 10px; - width: 10px; - margin: -5px; - scale: 0.5; -} - -@keyframes spin { - 0% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 6.25% { - box-shadow: - 0px -30px transparent, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 12.5% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 18.75% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 25% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 31.25% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } - 37.5% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px #000, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px transparent, - -10px -30px transparent; - } - 43.75% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px #000, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px transparent; - } - 50% { - box-shadow: - 0px -30px transparent, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px #000, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 56.25% { - box-shadow: - 0px -30px #000, - 10px -30px transparent, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px #000, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 62.5% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px transparent, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px #000, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 68.75% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px transparent, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px #000, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 75% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px transparent, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px #000, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 81.25% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px transparent, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px #000, - -20px -20px #000, - -10px -30px #000; - } - 87.5% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px transparent, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px #000, - -10px -30px #000; - } - 93.75% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px transparent, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px #000; - } - 100% { - box-shadow: - 0px -30px #000, - 10px -30px #000, - 20px -20px #000, - 30px -10px #000, - 30px 0px #000, - 30px 10px #000, - 20px 20px #000, - 10px 30px #000, - 0px 30px transparent, - -10px 30px transparent, - -20px 20px transparent, - -30px 10px transparent, - -30px 0px transparent, - -30px -10px transparent, - -20px -20px transparent, - -10px -30px transparent; - } -} - diff --git a/examples/ratchet-phi/src/app/layout.tsx b/examples/ratchet-phi/src/app/layout.tsx deleted file mode 100644 index 90602f5d..00000000 --- a/examples/ratchet-phi/src/app/layout.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import type { Metadata } from "next"; -import { Inter } from "next/font/google"; -import "./globals.css"; -import { Toaster } from "react-hot-toast"; -import "react-responsive-modal/styles.css"; - -const inter = Inter({ subsets: ["latin"] }); - -export const metadata: Metadata = { - title: "Ratchet + Phi", - description: "Simple demo of Phi.", -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - -
- -
{children}
-
- - - ); -} diff --git a/examples/ratchet-phi/src/app/page.module.css b/examples/ratchet-phi/src/app/page.module.css deleted file mode 100644 index c13f8527..00000000 --- a/examples/ratchet-phi/src/app/page.module.css +++ /dev/null @@ -1,236 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; - text-wrap: balance; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} - -.buttonsContainer { - display: flex; - justify-content: center; /* Center buttons horizontally */ - gap: 10px; /* Add some space between the buttons */ -} diff --git a/examples/ratchet-phi/src/app/page.tsx b/examples/ratchet-phi/src/app/page.tsx deleted file mode 100644 index d9f3aa86..00000000 --- a/examples/ratchet-phi/src/app/page.tsx +++ /dev/null @@ -1,140 +0,0 @@ -'use client' - -import { AvailableModels, Model, Quantization, default as init } from "@ratchet-ml/ratchet-web"; -import { useEffect, useState } from "react"; -import ProgressBar from "./components/progressBar"; -import WebGPUModal from "./components/WebGPUModal"; -import WarningModal from "./components/warningModal"; - -export default function Home() { - const [selectedModel, setSelectedModel] = useState({ Phi: "phi3" }); - const [loadedModel, setLoadedModel] = useState(null); - const [model, setModel] = useState(null); - const [generating, setGenerating] = useState(false); - const [progress, setProgress] = useState(0); - const [generatedText, setGeneratedText] = useState(""); - const [prompt, setPrompt] = useState("What is the meaning of life?"); - const [loadingModel, setLoadingModel] = useState(false); - const [isWarningOpen, setIsWarningOpen] = useState(false); - const [ratchetDBExists, setRatchetDBExists] = useState(false); - - - useEffect(() => { - (async () => { - await init(); - setRatchetDBExists((await window.indexedDB.databases()).map(db => db.name).includes("ratchet")); - })(); - }, []); - - async function loadModel() { - setLoadingModel(true); - setModel(await Model.load(selectedModel, Quantization.Q8_0, (p: number) => setProgress(p))); - setLoadedModel(selectedModel); - setProgress(0); - setLoadingModel(false); - } - - async function runModel() { - if (!model || generating) { - return; - } - - setGenerating(true); - setGeneratedText(""); - - let cb = (s: string) => { - setGeneratedText((prevText) => { - return prevText + s.replace(/\n/g, "
"); - }); - }; - - let input = { - prompt: prompt, - callback: cb, - }; - - await model.run(input); - setGenerating(false); - } - - return ( -
-
-

Ratchet + Phi3

- {generatedText ? -
-

-
- : <>} -
- -
- -