From 6f577575c74e47a1938161f0c17a202511a2552b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Hatcher?= Date: Sun, 23 Mar 2025 01:51:17 +0100 Subject: [PATCH] UPDATE: Dynamic arrays! --- base/src/actions.rs | 2 +- base/src/arithmetic.rs | 8 - base/src/cell.rs | 100 +- .../src/expressions/parser/static_analysis.rs | 4 +- base/src/functions/subtotal.rs | 2 +- base/src/model.rs | 509 ++++++-- base/src/new_empty.rs | 4 +- base/src/test/mod.rs | 1 + base/src/test/test_dynamic_arrays.rs | 50 + base/src/test/test_implicit_intersection.rs | 4 +- base/src/test/user_model/mod.rs | 2 + .../test/user_model/test_delete_evaluates.rs | 47 + .../src/test/user_model/test_dynamic_array.rs | 130 ++ base/src/types.rs | 85 +- base/src/user_model/common.rs | 95 +- base/src/user_model/history.rs | 3 + bindings/wasm/fix_types.py | 13 + bindings/wasm/src/lib.rs | 14 + bindings/wasm/types.ts | 9 +- webapp/IronCalc/package-lock.json | 1047 +++++++++-------- .../src/components/FormulaBar/FormulaBar.tsx | 5 + .../src/components/Workbook/Workbook.tsx | 14 + .../src/components/Worksheet/Worksheet.tsx | 14 +- .../components/WorksheetCanvas/constants.ts | 1 + .../WorksheetCanvas/worksheetCanvas.ts | 38 +- xlsx/src/export/worksheets.rs | 144 ++- xlsx/src/import/worksheets.rs | 10 +- xlsx/tests/calc_tests/simple_spill.xlsx | Bin 0 -> 11921 bytes 28 files changed, 1714 insertions(+), 641 deletions(-) create mode 100644 base/src/test/test_dynamic_arrays.rs create mode 100644 base/src/test/user_model/test_delete_evaluates.rs create mode 100644 base/src/test/user_model/test_dynamic_array.rs create mode 100644 xlsx/tests/calc_tests/simple_spill.xlsx diff --git a/base/src/actions.rs b/base/src/actions.rs index cbcb816..328ab4e 100644 --- a/base/src/actions.rs +++ b/base/src/actions.rs @@ -22,7 +22,7 @@ impl Model { .cell(row, column) .and_then(|c| c.get_formula()) { - let node = &self.parsed_formulas[sheet as usize][f as usize].clone(); + let node = &self.parsed_formulas[sheet as usize][f as usize].0.clone(); let cell_reference = CellReferenceRC { sheet: self.workbook.worksheets[sheet as usize].get_name(), row, diff --git a/base/src/arithmetic.rs b/base/src/arithmetic.rs index 26f729d..cd9d529 100644 --- a/base/src/arithmetic.rs +++ b/base/src/arithmetic.rs @@ -77,8 +77,6 @@ impl Model { match to_f64(&node) { Ok(f2) => match op(f1, f2) { Ok(x) => data_row.push(ArrayNode::Number(x)), - Err(Error::DIV) => data_row.push(ArrayNode::Error(Error::DIV)), - Err(Error::VALUE) => data_row.push(ArrayNode::Error(Error::VALUE)), Err(e) => data_row.push(ArrayNode::Error(e)), }, Err(err) => data_row.push(ArrayNode::Error(err)), @@ -100,8 +98,6 @@ impl Model { match to_f64(&node) { Ok(f1) => match op(f1, f2) { Ok(x) => data_row.push(ArrayNode::Number(x)), - Err(Error::DIV) => data_row.push(ArrayNode::Error(Error::DIV)), - Err(Error::VALUE) => data_row.push(ArrayNode::Error(Error::VALUE)), Err(e) => data_row.push(ArrayNode::Error(e)), }, Err(err) => data_row.push(ArrayNode::Error(err)), @@ -137,10 +133,6 @@ impl Model { (Some(v1), Some(v2)) => match (to_f64(v1), to_f64(v2)) { (Ok(f1), Ok(f2)) => match op(f1, f2) { Ok(x) => data_row.push(ArrayNode::Number(x)), - Err(Error::DIV) => data_row.push(ArrayNode::Error(Error::DIV)), - Err(Error::VALUE) => { - data_row.push(ArrayNode::Error(Error::VALUE)) - } Err(e) => data_row.push(ArrayNode::Error(e)), }, (Err(e), _) | (_, Err(e)) => data_row.push(ArrayNode::Error(e)), diff --git a/base/src/cell.rs b/base/src/cell.rs index 70299f1..3fbbf4e 100644 --- a/base/src/cell.rs +++ b/base/src/cell.rs @@ -64,12 +64,50 @@ impl Cell { /// Returns the formula of a cell if any. pub fn get_formula(&self) -> Option { match self { - Cell::CellFormula { f, .. } => Some(*f), - Cell::CellFormulaBoolean { f, .. } => Some(*f), - Cell::CellFormulaNumber { f, .. } => Some(*f), - Cell::CellFormulaString { f, .. } => Some(*f), - Cell::CellFormulaError { f, .. } => Some(*f), - _ => None, + Cell::CellFormula { f, .. } + | Cell::CellFormulaBoolean { f, .. } + | Cell::CellFormulaNumber { f, .. } + | Cell::CellFormulaString { f, .. } + | Cell::CellFormulaError { f, .. } + | Cell::DynamicCellFormula { f, .. } + | Cell::DynamicCellFormulaBoolean { f, .. } + | Cell::DynamicCellFormulaNumber { f, .. } + | Cell::DynamicCellFormulaString { f, .. } + | Cell::DynamicCellFormulaError { f, .. } => Some(*f), + Cell::EmptyCell { .. } + | Cell::BooleanCell { .. } + | Cell::NumberCell { .. } + | Cell::ErrorCell { .. } + | Cell::SharedString { .. } + | Cell::SpillNumberCell { .. } + | Cell::SpillBooleanCell { .. } + | Cell::SpillErrorCell { .. } + | Cell::SpillStringCell { .. } => None, + } + } + + /// Returns the dynamic range of a cell if any. + pub fn get_dynamic_range(&self) -> Option<(i32, i32)> { + match self { + Cell::DynamicCellFormula { r, .. } => Some(*r), + Cell::DynamicCellFormulaBoolean { r, .. } => Some(*r), + Cell::DynamicCellFormulaNumber { r, .. } => Some(*r), + Cell::DynamicCellFormulaString { r, .. } => Some(*r), + Cell::DynamicCellFormulaError { r, .. } => Some(*r), + Cell::EmptyCell { .. } + | Cell::BooleanCell { .. } + | Cell::NumberCell { .. } + | Cell::ErrorCell { .. } + | Cell::SharedString { .. } + | Cell::CellFormula { .. } + | Cell::CellFormulaBoolean { .. } + | Cell::CellFormulaNumber { .. } + | Cell::CellFormulaString { .. } + | Cell::CellFormulaError { .. } + | Cell::SpillNumberCell { .. } + | Cell::SpillBooleanCell { .. } + | Cell::SpillErrorCell { .. } + | Cell::SpillStringCell { .. } => None, } } @@ -89,6 +127,15 @@ impl Cell { Cell::CellFormulaNumber { s, .. } => *s = style, Cell::CellFormulaString { s, .. } => *s = style, Cell::CellFormulaError { s, .. } => *s = style, + Cell::SpillBooleanCell { s, .. } => *s = style, + Cell::SpillNumberCell { s, .. } => *s = style, + Cell::SpillStringCell { s, .. } => *s = style, + Cell::SpillErrorCell { s, .. } => *s = style, + Cell::DynamicCellFormula { s, .. } => *s = style, + Cell::DynamicCellFormulaBoolean { s, .. } => *s = style, + Cell::DynamicCellFormulaNumber { s, .. } => *s = style, + Cell::DynamicCellFormulaString { s, .. } => *s = style, + Cell::DynamicCellFormulaError { s, .. } => *s = style, }; } @@ -104,6 +151,15 @@ impl Cell { Cell::CellFormulaNumber { s, .. } => *s, Cell::CellFormulaString { s, .. } => *s, Cell::CellFormulaError { s, .. } => *s, + Cell::SpillBooleanCell { s, .. } => *s, + Cell::SpillNumberCell { s, .. } => *s, + Cell::SpillStringCell { s, .. } => *s, + Cell::SpillErrorCell { s, .. } => *s, + Cell::DynamicCellFormula { s, .. } => *s, + Cell::DynamicCellFormulaBoolean { s, .. } => *s, + Cell::DynamicCellFormulaNumber { s, .. } => *s, + Cell::DynamicCellFormulaString { s, .. } => *s, + Cell::DynamicCellFormulaError { s, .. } => *s, } } @@ -119,6 +175,15 @@ impl Cell { Cell::CellFormulaNumber { .. } => CellType::Number, Cell::CellFormulaString { .. } => CellType::Text, Cell::CellFormulaError { .. } => CellType::ErrorValue, + Cell::SpillBooleanCell { .. } => CellType::LogicalValue, + Cell::SpillNumberCell { .. } => CellType::Number, + Cell::SpillStringCell { .. } => CellType::Text, + Cell::SpillErrorCell { .. } => CellType::ErrorValue, + Cell::DynamicCellFormula { .. } => CellType::Number, + Cell::DynamicCellFormulaBoolean { .. } => CellType::LogicalValue, + Cell::DynamicCellFormulaNumber { .. } => CellType::Number, + Cell::DynamicCellFormulaString { .. } => CellType::Text, + Cell::DynamicCellFormulaError { .. } => CellType::ErrorValue, } } @@ -136,7 +201,7 @@ impl Cell { Cell::EmptyCell { .. } => CellValue::None, Cell::BooleanCell { v, s: _ } => CellValue::Boolean(*v), Cell::NumberCell { v, s: _ } => CellValue::Number(*v), - Cell::ErrorCell { ei, .. } => { + Cell::ErrorCell { ei, .. } | Cell::SpillErrorCell { ei, .. } => { let v = ei.to_localized_error_string(language); CellValue::String(v) } @@ -148,14 +213,25 @@ impl Cell { }; CellValue::String(v) } - Cell::CellFormula { .. } => CellValue::String("#ERROR!".to_string()), - Cell::CellFormulaBoolean { v, .. } => CellValue::Boolean(*v), - Cell::CellFormulaNumber { v, .. } => CellValue::Number(*v), - Cell::CellFormulaString { v, .. } => CellValue::String(v.clone()), - Cell::CellFormulaError { ei, .. } => { + Cell::DynamicCellFormula { .. } | Cell::CellFormula { .. } => { + CellValue::String("#ERROR!".to_string()) + } + Cell::DynamicCellFormulaBoolean { v, .. } | Cell::CellFormulaBoolean { v, .. } => { + CellValue::Boolean(*v) + } + Cell::DynamicCellFormulaNumber { v, .. } | Cell::CellFormulaNumber { v, .. } => { + CellValue::Number(*v) + } + Cell::DynamicCellFormulaString { v, .. } | Cell::CellFormulaString { v, .. } => { + CellValue::String(v.clone()) + } + Cell::DynamicCellFormulaError { ei, .. } | Cell::CellFormulaError { ei, .. } => { let v = ei.to_localized_error_string(language); CellValue::String(v) } + Cell::SpillBooleanCell { v, .. } => CellValue::Boolean(*v), + Cell::SpillNumberCell { v, .. } => CellValue::Number(*v), + Cell::SpillStringCell { v, .. } => CellValue::String(v.clone()), } } diff --git a/base/src/expressions/parser/static_analysis.rs b/base/src/expressions/parser/static_analysis.rs index 280ac24..01091ae 100644 --- a/base/src/expressions/parser/static_analysis.rs +++ b/base/src/expressions/parser/static_analysis.rs @@ -182,7 +182,7 @@ pub fn add_implicit_intersection(node: &mut Node, add: bool) { }; } -pub(crate) enum StaticResult { +pub enum StaticResult { Scalar, Array(i32, i32), Range(i32, i32), @@ -218,7 +218,7 @@ fn static_analysis_op_nodes(left: &Node, right: &Node) -> StaticResult { // * Array(a, b) if we know it will be an a x b array. // * Range(a, b) if we know it will be a a x b range. // * Unknown if we cannot guaranty either -fn run_static_analysis_on_node(node: &Node) -> StaticResult { +pub(crate) fn run_static_analysis_on_node(node: &Node) -> StaticResult { match node { Node::BooleanKind(_) | Node::NumberKind(_) diff --git a/base/src/functions/subtotal.rs b/base/src/functions/subtotal.rs index cd3f49b..5709197 100644 --- a/base/src/functions/subtotal.rs +++ b/base/src/functions/subtotal.rs @@ -96,7 +96,7 @@ impl Model { match cell.get_formula() { Some(f) => { - let node = &self.parsed_formulas[sheet_index as usize][f as usize]; + let node = &self.parsed_formulas[sheet_index as usize][f as usize].0; matches!( node, Node::FunctionKind { diff --git a/base/src/model.rs b/base/src/model.rs index 7ceb536..5f5c280 100644 --- a/base/src/model.rs +++ b/base/src/model.rs @@ -11,8 +11,9 @@ use crate::{ lexer::LexerMode, parser::{ move_formula::{move_formula, MoveContext}, + static_analysis::{run_static_analysis_on_node, StaticResult}, stringify::{rename_defined_name_in_node, to_rc_format, to_string}, - Node, Parser, + ArrayNode, Node, Parser, }, token::{get_error_by_name, Error, OpCompare, OpProduct, OpSum, OpUnary}, types::*, @@ -99,7 +100,7 @@ pub struct Model { /// A Rust internal representation of an Excel workbook pub workbook: Workbook, /// A list of parsed formulas - pub parsed_formulas: Vec>, + pub parsed_formulas: Vec>, /// A list of parsed defined names pub(crate) parsed_defined_names: HashMap<(Option, String), ParsedDefinedName>, /// An optimization to lookup strings faster @@ -522,14 +523,195 @@ impl Model { } Ok(format!("{}!{}{}", sheet.name, column, cell_reference.row)) } + + /// Sets sheet, target_row, target_column, (width, height), &v + #[allow(clippy::too_many_arguments)] + fn set_spill_cell_with_formula_value( + &mut self, + sheet: u32, + row: i32, + column: i32, + r: (i32, i32), + v: &CalcResult, + s: i32, + f: i32, + ) -> Result<(), String> { + let new_cell = match v { + CalcResult::EmptyCell => Cell::DynamicCellFormulaNumber { + f, + v: 0.0, + s, + r, + a: false, + }, + CalcResult::String(v) => Cell::DynamicCellFormulaString { + f, + v: v.clone(), + s, + r, + a: false, + }, + CalcResult::Number(v) => Cell::DynamicCellFormulaNumber { + v: *v, + s, + r, + f, + a: false, + }, + CalcResult::Boolean(b) => Cell::DynamicCellFormulaBoolean { + v: *b, + s, + r, + f, + a: false, + }, + CalcResult::Error { error, .. } => Cell::DynamicCellFormulaError { + ei: error.clone(), + s, + r, + f, + a: false, + o: "".to_string(), + m: "".to_string(), + }, + + // These cannot happen + // FIXME: Maybe the type of get_cell_value should be different + CalcResult::Range { .. } | CalcResult::EmptyArg | CalcResult::Array(_) => { + Cell::DynamicCellFormulaError { + ei: Error::ERROR, + s, + r, + f, + a: false, + o: "".to_string(), + m: "".to_string(), + } + } + }; + let sheet_data = &mut self.workbook.worksheet_mut(sheet)?.sheet_data; + + match sheet_data.get_mut(&row) { + Some(column_data) => match column_data.get(&column) { + Some(_cell) => { + column_data.insert(column, new_cell); + } + None => { + column_data.insert(column, new_cell); + } + }, + None => { + let mut column_data = HashMap::new(); + column_data.insert(column, new_cell); + sheet_data.insert(row, column_data); + } + } + Ok(()) + } + + /// Sets a cell with a "spill" value + fn set_spill_cell_with_value( + &mut self, + sheet: u32, + row: i32, + column: i32, + m: (i32, i32), + v: &CalcResult, + ) -> Result<(), String> { + let style_index = self.get_cell_style_index(sheet, row, column)?; + let new_style_index = if self.workbook.styles.style_is_quote_prefix(style_index) { + self.workbook + .styles + .get_style_without_quote_prefix(style_index)? + } else { + style_index + }; + let new_cell = match v { + CalcResult::EmptyCell => Cell::SpillNumberCell { + v: 0.0, + s: style_index, + m, + }, + CalcResult::String(s) => Cell::SpillStringCell { + v: s.clone(), + s: new_style_index, + m, + }, + CalcResult::Number(f) => Cell::SpillNumberCell { + v: *f, + s: new_style_index, + m, + }, + CalcResult::Boolean(b) => Cell::SpillBooleanCell { + v: *b, + s: new_style_index, + m, + }, + CalcResult::Error { error, .. } => Cell::SpillErrorCell { + ei: error.clone(), + s: style_index, + m, + }, + + // These cannot happen + // FIXME: Maybe the type of get_cell_value should be different + CalcResult::Range { .. } | CalcResult::EmptyArg | CalcResult::Array(_) => { + Cell::SpillErrorCell { + ei: Error::ERROR, + s: style_index, + m, + } + } + }; + let sheet_data = &mut self.workbook.worksheet_mut(sheet)?.sheet_data; + + match sheet_data.get_mut(&row) { + Some(column_data) => match column_data.get(&column) { + Some(_cell) => { + column_data.insert(column, new_cell); + } + None => { + column_data.insert(column, new_cell); + } + }, + None => { + let mut column_data = HashMap::new(); + column_data.insert(column, new_cell); + sheet_data.insert(row, column_data); + } + } + Ok(()) + } + /// Sets `result` in the cell given by `sheet` sheet index, row and column /// Note that will panic if the cell does not exist /// It will do nothing if the cell does not have a formula #[allow(clippy::expect_used)] - fn set_cell_value(&mut self, cell_reference: CellReferenceIndex, result: &CalcResult) { + fn set_cell_value( + &mut self, + cell_reference: CellReferenceIndex, + result: &CalcResult, + ) -> Result<(), String> { let CellReferenceIndex { sheet, column, row } = cell_reference; - let cell = &self.workbook.worksheets[sheet as usize].sheet_data[&row][&column]; + let cell = self + .workbook + .worksheet(sheet)? + .cell(row, column) + .cloned() + .unwrap_or_default(); let s = cell.get_style(); + // If the cell is a dynamic cell we need to delete all the cells in the range + if let Some((width, height)) = cell.get_dynamic_range() { + for r in row..row + height { + for c in column..column + width { + // skip the "mother" cell + if r == row && c == column { + continue; + } + self.cell_clear_contents(sheet, r, c)?; + } + } + } if let Some(f) = cell.get_formula() { match result { CalcResult::Number(value) => { @@ -594,19 +776,138 @@ impl Model { ei: error.clone(), }; } + CalcResult::EmptyCell | CalcResult::EmptyArg => { + *self.workbook.worksheets[sheet as usize] + .sheet_data + .get_mut(&row) + .expect("expected a row") + .get_mut(&column) + .expect("expected a column") = Cell::CellFormulaNumber { f, s, v: 0.0 }; + } CalcResult::Range { left, right } => { if left.sheet == right.sheet && left.row == right.row && left.column == right.column { - let intersection_cell = CellReferenceIndex { + // There is only one cell + let single_cell = CellReferenceIndex { sheet: left.sheet, column: left.column, row: left.row, }; - let v = self.evaluate_cell(intersection_cell); - self.set_cell_value(cell_reference, &v); + let v = self.evaluate_cell(single_cell); + self.set_cell_value(cell_reference, &v)?; } else { + // We need to check if all the cells are empty, otherwise we mark the cell as #SPILL! + let mut all_empty = true; + for r in row..=row + right.row - left.row { + for c in column..=column + right.column - left.column { + if r == row && c == column { + continue; + } + if !self.is_empty_cell(sheet, r, c).unwrap_or(false) { + all_empty = false; + break; + } + } + } + if !all_empty { + let o = match self.cell_reference_to_string(&cell_reference) { + Ok(s) => s, + Err(_) => "".to_string(), + }; + *self.workbook.worksheets[sheet as usize] + .sheet_data + .get_mut(&row) + .expect("expected a row") + .get_mut(&column) + .expect("expected a column") = Cell::DynamicCellFormulaError { + f, + s, + o, + m: "Result would spill to non empty cells".to_string(), + ei: Error::SPILL, + r: (1, 1), + a: false, + }; + return Ok(()); + } + // evaluate all the cells in that range + for r in left.row..=right.row { + for c in left.column..=right.column { + let cell_reference = CellReferenceIndex { + sheet: left.sheet, + row: r, + column: c, + }; + // FIXME: We ned to return an error + self.evaluate_cell(cell_reference); + } + } + // now write the result in the target + for r in left.row..=right.row { + let row_delta = r - left.row; + for c in left.column..=right.column { + let column_delta = c - left.column; + // We need to put whatever is in (left.sheet, r, c) in + // (sheet, row + row_delta, column + column_delta) + // But we need to preserve the style + let target_row = row + row_delta; + let target_column = column + column_delta; + let cell = self + .workbook + .worksheet(left.sheet)? + .cell(r, c) + .cloned() + .unwrap_or_default(); + let cell_reference = CellReferenceIndex { + sheet: left.sheet, + row: r, + column: c, + }; + let v = self.get_cell_value(&cell, cell_reference); + if row == target_row && column == target_column { + // let cell_reference = CellReferenceIndex { sheet, row, column }; + // self.set_cell_value(cell_reference, &v); + self.set_spill_cell_with_formula_value( + sheet, + target_row, + target_column, + (right.column - left.column + 1, right.row - left.row + 1), + &v, + s, + f, + )?; + continue; + } + self.set_spill_cell_with_value( + sheet, + target_row, + target_column, + (row, column), + &v, + )?; + } + } + } + } + CalcResult::Array(array) => { + let width = array[0].len() as i32; + let height = array.len() as i32; + // First we check that we don't spill: + let mut all_empty = true; + for r in row..row + height { + for c in column..column + width { + if r == row && c == column { + continue; + } + if !self.is_empty_cell(sheet, r, c).unwrap_or(false) { + all_empty = false; + break; + } + } + } + if !all_empty { let o = match self.cell_reference_to_string(&cell_reference) { Ok(s) => s, Err(_) => "".to_string(), @@ -620,57 +921,65 @@ impl Model { f, s, o, - m: "Implicit Intersection not implemented".to_string(), - ei: Error::NIMPL, + m: "Result would spill to non empty cells".to_string(), + ei: Error::SPILL, }; + return Ok(()); + } + let mut target_row = row; + for data_row in array { + let mut target_column = column; + for value in data_row { + if row == target_row && column == target_column { + // This is the root cell of the dynamic array + let cell_reference = CellReferenceIndex { sheet, row, column }; + let v = match value { + ArrayNode::Boolean(b) => CalcResult::Boolean(*b), + ArrayNode::Number(f) => CalcResult::Number(*f), + ArrayNode::String(s) => CalcResult::String(s.clone()), + ArrayNode::Error(error) => CalcResult::new_error( + error.clone(), + cell_reference, + error.to_localized_error_string(&self.language), + ), + }; + self.set_spill_cell_with_formula_value( + sheet, + target_row, + target_column, + (width, height), + &v, + s, + f, + )?; + target_column += 1; + continue; + } + let v = match value { + ArrayNode::Boolean(b) => CalcResult::Boolean(*b), + ArrayNode::Number(f) => CalcResult::Number(*f), + ArrayNode::String(s) => CalcResult::String(s.clone()), + ArrayNode::Error(error) => CalcResult::new_error( + error.clone(), + cell_reference, + error.to_localized_error_string(&self.language), + ), + }; + self.set_spill_cell_with_value( + sheet, + target_row, + target_column, + (row, column), + &v, + )?; + target_column += 1; + } + target_row += 1; } - // if let Some(intersection_cell) = implicit_intersection(&cell_reference, &range) - // { - // let v = self.evaluate_cell(intersection_cell); - // self.set_cell_value(cell_reference, &v); - // } else { - // let o = match self.cell_reference_to_string(&cell_reference) { - // Ok(s) => s, - // Err(_) => "".to_string(), - // }; - // *self.workbook.worksheets[sheet as usize] - // .sheet_data - // .get_mut(&row) - // .expect("expected a row") - // .get_mut(&column) - // .expect("expected a column") = Cell::CellFormulaError { - // f, - // s, - // o, - // m: "Invalid reference".to_string(), - // ei: Error::VALUE, - // }; - // } - } - CalcResult::EmptyCell | CalcResult::EmptyArg => { - *self.workbook.worksheets[sheet as usize] - .sheet_data - .get_mut(&row) - .expect("expected a row") - .get_mut(&column) - .expect("expected a column") = Cell::CellFormulaNumber { f, s, v: 0.0 }; - } - CalcResult::Array(_) => { - *self.workbook.worksheets[sheet as usize] - .sheet_data - .get_mut(&row) - .expect("expected a row") - .get_mut(&column) - .expect("expected a column") = Cell::CellFormulaError { - f, - s, - o: "".to_string(), - m: "Arrays not supported yet".to_string(), - ei: Error::NIMPL, - }; } } } + Ok(()) } /// Sets the color of the sheet tab. @@ -714,16 +1023,18 @@ impl Model { Ok(()) } + // EmptyCell, Boolean, Number, String, Error fn get_cell_value(&self, cell: &Cell, cell_reference: CellReferenceIndex) -> CalcResult { use Cell::*; match cell { EmptyCell { .. } => CalcResult::EmptyCell, - BooleanCell { v, .. } => CalcResult::Boolean(*v), - NumberCell { v, .. } => CalcResult::Number(*v), - ErrorCell { ei, .. } => { + BooleanCell { v, .. } | SpillBooleanCell { v, .. } => CalcResult::Boolean(*v), + NumberCell { v, .. } | SpillNumberCell { v, .. } => CalcResult::Number(*v), + ErrorCell { ei, .. } | SpillErrorCell { ei, .. } => { let message = ei.to_localized_error_string(&self.language); CalcResult::new_error(ei.clone(), cell_reference, message) } + SpillStringCell { v, .. } => CalcResult::String(v.clone()), SharedString { si, .. } => { if let Some(s) = self.workbook.shared_strings.get(*si as usize) { CalcResult::String(s.clone()) @@ -732,15 +1043,21 @@ impl Model { CalcResult::new_error(Error::ERROR, cell_reference, message) } } - CellFormula { .. } => CalcResult::Error { + DynamicCellFormula { .. } | CellFormula { .. } => CalcResult::Error { error: Error::ERROR, origin: cell_reference, message: "Unevaluated formula".to_string(), }, - CellFormulaBoolean { v, .. } => CalcResult::Boolean(*v), - CellFormulaNumber { v, .. } => CalcResult::Number(*v), - CellFormulaString { v, .. } => CalcResult::String(v.clone()), - CellFormulaError { ei, o, m, .. } => { + DynamicCellFormulaBoolean { v, .. } | CellFormulaBoolean { v, .. } => { + CalcResult::Boolean(*v) + } + DynamicCellFormulaNumber { v, .. } | CellFormulaNumber { v, .. } => { + CalcResult::Number(*v) + } + DynamicCellFormulaString { v, .. } | CellFormulaString { v, .. } => { + CalcResult::String(v.clone()) + } + DynamicCellFormulaError { ei, o, m, .. } | CellFormulaError { ei, o, m, .. } => { if let Some(cell_reference) = self.parse_reference(o) { CalcResult::new_error(ei.clone(), cell_reference, m.clone()) } else { @@ -810,9 +1127,10 @@ impl Model { self.cells.insert(key, CellState::Evaluating); } } - let node = &self.parsed_formulas[cell_reference.sheet as usize][f as usize].clone(); - let result = self.evaluate_node_in_context(node, cell_reference); - self.set_cell_value(cell_reference, &result); + let (node, _static_result) = + &self.parsed_formulas[cell_reference.sheet as usize][f as usize]; + let result = self.evaluate_node_in_context(&node.clone(), cell_reference); + let _ = self.set_cell_value(cell_reference, &result); // mark cell as evaluated self.cells.insert(key, CellState::Evaluated); result @@ -1100,7 +1418,7 @@ impl Model { Some(cell) => match cell.get_formula() { None => cell.get_text(&self.workbook.shared_strings, &self.language), Some(i) => { - let formula = &self.parsed_formulas[sheet as usize][i as usize]; + let formula = &self.parsed_formulas[sheet as usize][i as usize].0; let cell_ref = CellReferenceRC { sheet: self.workbook.worksheets[sheet as usize].get_name(), row: target_row, @@ -1203,7 +1521,8 @@ impl Model { .get(sheet as usize) .ok_or("missing sheet")? .get(formula_index as usize) - .ok_or("missing formula")?; + .ok_or("missing formula")? + .0; let cell_ref = CellReferenceRC { sheet: worksheet.get_name(), row, @@ -1437,6 +1756,25 @@ impl Model { column: i32, value: String, ) -> Result<(), String> { + // We need to check if the cell is part of a dynamic array + let cell = self + .workbook + .worksheet(sheet)? + .cell(row, column) + .cloned() + .unwrap_or_default(); + // If the cell is a dynamic cell we need to delete all the cells in the range + if let Some((width, height)) = cell.get_dynamic_range() { + for r in row..row + height { + for c in column..column + width { + // skip the "mother" cell + if r == row && c == column { + continue; + } + self.cell_clear_contents(sheet, r, c)?; + } + } + } // If value starts with "'" then we force the style to be quote_prefix let style_index = self.get_cell_style_index(sheet, row, column)?; if let Some(new_value) = value.strip_prefix('\'') { @@ -1462,7 +1800,8 @@ impl Model { self.set_cell_with_formula(sheet, row, column, formula, new_style_index)?; // Update the style if needed let cell = CellReferenceIndex { sheet, row, column }; - let parsed_formula = &self.parsed_formulas[sheet as usize][formula_index as usize]; + let parsed_formula = + &self.parsed_formulas[sheet as usize][formula_index as usize].0; if let Some(units) = self.compute_node_units(parsed_formula, &cell) { let new_style_index = self .workbook @@ -1544,6 +1883,7 @@ impl Model { _ => parsed_formula = new_parsed_formula, } } + let static_result = run_static_analysis_on_node(&parsed_formula); let s = to_rc_format(&parsed_formula); let mut formula_index: i32 = -1; @@ -1552,7 +1892,7 @@ impl Model { } if formula_index == -1 { shared_formulas.push(s); - self.parsed_formulas[sheet as usize].push(parsed_formula); + self.parsed_formulas[sheet as usize].push((parsed_formula, static_result)); formula_index = (shared_formulas.len() as i32) - 1; } worksheet.set_cell_with_formula(row, column, formula_index, style)?; @@ -1747,7 +2087,7 @@ impl Model { }; match cell.get_formula() { Some(formula_index) => { - let formula = &self.parsed_formulas[sheet as usize][formula_index as usize]; + let formula = &self.parsed_formulas[sheet as usize][formula_index as usize].0; let cell_ref = CellReferenceRC { sheet: worksheet.get_name(), row, @@ -1818,9 +2158,22 @@ impl Model { /// # } /// ``` pub fn cell_clear_contents(&mut self, sheet: u32, row: i32, column: i32) -> Result<(), String> { - self.workbook - .worksheet_mut(sheet)? - .cell_clear_contents(row, column)?; + // If it has a spill formula we need to delete the contents of all the spilled cells + let worksheet = self.workbook.worksheet_mut(sheet)?; + if let Some(cell) = worksheet.cell(row, column) { + if let Some((width, height)) = cell.get_dynamic_range() { + for r in row..row + height { + for c in column..column + width { + if row == r && column == c { + // we skip the root cell + continue; + } + worksheet.cell_clear_contents(r, c)?; + } + } + } + } + worksheet.cell_clear_contents(row, column)?; Ok(()) } @@ -1845,6 +2198,18 @@ impl Model { /// # } pub fn cell_clear_all(&mut self, sheet: u32, row: i32, column: i32) -> Result<(), String> { let worksheet = self.workbook.worksheet_mut(sheet)?; + // Delete the contents of spilled cells if any + if let Some(cell) = worksheet.cell(row, column) { + if let Some((width, height)) = cell.get_dynamic_range() { + for r in row..row + height { + for c in column..column + width { + if row == r && c == column { + worksheet.cell_clear_contents(r, c)?; + } + } + } + } + } let sheet_data = &mut worksheet.sheet_data; if let Some(row_data) = sheet_data.get_mut(&row) { diff --git a/base/src/new_empty.rs b/base/src/new_empty.rs index a07b30e..2f1eddc 100644 --- a/base/src/new_empty.rs +++ b/base/src/new_empty.rs @@ -8,6 +8,7 @@ use crate::{ expressions::{ lexer::LexerMode, parser::{ + static_analysis::run_static_analysis_on_node, stringify::{rename_sheet_in_node, to_rc_format, to_string}, Parser, }, @@ -94,7 +95,8 @@ impl Model { let mut parse_formula = Vec::new(); for formula in shared_formulas { let t = self.parser.parse(formula, &cell_reference); - parse_formula.push(t); + let static_result = run_static_analysis_on_node(&t); + parse_formula.push((t, static_result)); } self.parsed_formulas.push(parse_formula); } diff --git a/base/src/test/mod.rs b/base/src/test/mod.rs index 8e1b4eb..e1628ec 100644 --- a/base/src/test/mod.rs +++ b/base/src/test/mod.rs @@ -52,6 +52,7 @@ mod test_fn_offset; mod test_number_format; mod test_arrays; +mod test_dynamic_arrays; mod test_escape_quotes; mod test_extend; mod test_fn_fv; diff --git a/base/src/test/test_dynamic_arrays.rs b/base/src/test/test_dynamic_arrays.rs new file mode 100644 index 0000000..252b5bc --- /dev/null +++ b/base/src/test/test_dynamic_arrays.rs @@ -0,0 +1,50 @@ +#![allow(clippy::unwrap_used)] + +use crate::test::util::new_empty_model; + +#[test] +fn they_spill() { + let mut model = new_empty_model(); + model._set("A1", "42"); + model._set("A2", "5"); + model._set("A3", "7"); + + model._set("B1", "=A1:A3"); + + model.evaluate(); + + assert_eq!(model._get_text("B1"), *"42"); + assert_eq!(model._get_text("B2"), *"5"); + assert_eq!(model._get_text("B3"), *"7"); +} + +#[test] +fn spill_error() { + let mut model = new_empty_model(); + model._set("A1", "42"); + model._set("A2", "5"); + model._set("A3", "7"); + + model._set("B1", "=A1:A3"); + model._set("B2", "4"); + + model.evaluate(); + + assert_eq!(model._get_text("B1"), *"#SPILL!"); + assert_eq!(model._get_text("B2"), *"4"); + assert_eq!(model._get_text("B3"), *""); +} + +#[test] +fn second_evaluation() { + let mut model = new_empty_model(); + model._set("C3", "={1,2,3}"); + model.evaluate(); + + assert_eq!(model._get_text("D3"), "2"); + + model._set("D8", "23"); + model.evaluate(); + + assert_eq!(model._get_text("D3"), "2"); +} diff --git a/base/src/test/test_implicit_intersection.rs b/base/src/test/test_implicit_intersection.rs index 59687c1..24bcb0a 100644 --- a/base/src/test/test_implicit_intersection.rs +++ b/base/src/test/test_implicit_intersection.rs @@ -3,7 +3,7 @@ use crate::test::util::new_empty_model; #[test] -fn simple_colum() { +fn simple_column() { let mut model = new_empty_model(); // We populate cells A1 to A3 model._set("A1", "1"); @@ -30,7 +30,7 @@ fn return_of_array_is_n_impl() { model.evaluate(); - assert_eq!(model._get_text("C2"), "#N/IMPL!".to_string()); + assert_eq!(model._get_text("C2"), "1".to_string()); assert_eq!(model._get_text("D2"), "1.89188842".to_string()); } diff --git a/base/src/test/user_model/mod.rs b/base/src/test/user_model/mod.rs index 77f002c..e311c52 100644 --- a/base/src/test/user_model/mod.rs +++ b/base/src/test/user_model/mod.rs @@ -5,8 +5,10 @@ mod test_border; mod test_clear_cells; mod test_column_style; mod test_defined_names; +mod test_delete_evaluates; mod test_delete_row_column_formatting; mod test_diff_queue; +mod test_dynamic_array; mod test_evaluation; mod test_general; mod test_grid_lines; diff --git a/base/src/test/user_model/test_delete_evaluates.rs b/base/src/test/user_model/test_delete_evaluates.rs new file mode 100644 index 0000000..981d8cc --- /dev/null +++ b/base/src/test/user_model/test_delete_evaluates.rs @@ -0,0 +1,47 @@ +#![allow(clippy::unwrap_used)] + +use crate::{expressions::types::Area, UserModel}; + +#[test] +fn clear_cell_contents_evaluates() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "42").unwrap(); + model.set_user_input(0, 1, 2, "=A1").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("42".to_string()) + ); + model + .range_clear_contents(&Area { + sheet: 0, + row: 1, + column: 1, + width: 1, + height: 1, + }) + .unwrap(); + + assert_eq!(model.get_formatted_cell_value(0, 1, 2), Ok("0".to_string())); +} + +#[test] +fn clear_cell_all_evaluates() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "42").unwrap(); + model.set_user_input(0, 1, 2, "=A1").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("42".to_string()) + ); + model + .range_clear_all(&Area { + sheet: 0, + row: 1, + column: 1, + width: 1, + height: 1, + }) + .unwrap(); + + assert_eq!(model.get_formatted_cell_value(0, 1, 2), Ok("0".to_string())); +} diff --git a/base/src/test/user_model/test_dynamic_array.rs b/base/src/test/user_model/test_dynamic_array.rs new file mode 100644 index 0000000..351d177 --- /dev/null +++ b/base/src/test/user_model/test_dynamic_array.rs @@ -0,0 +1,130 @@ +#![allow(clippy::unwrap_used)] + +use crate::{expressions::types::Area, UserModel}; + +// Tests basic behavour. +#[test] +fn basic() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + // We put a value by the dynamic array to check the border conditions + model.set_user_input(0, 2, 1, "22").unwrap(); + model.set_user_input(0, 1, 1, "={34,35,3}").unwrap(); + + assert_eq!( + model.get_formatted_cell_value(0, 1, 1), + Ok("34".to_string()) + ); +} + +// Test that overwriting a dynamic array with a single value dissolves the array +#[test] +fn sett_user_input_mother() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "={34,35,3}").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("35".to_string()) + ); + model.set_user_input(0, 1, 1, "123").unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 2), Ok("".to_string())); +} + +#[test] +fn set_user_input_sibling() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "={43,55,34}").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("55".to_string()) + ); + // This does nothing + model.set_user_input(0, 1, 2, "123").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("55".to_string()) + ); +} + +#[test] +fn basic_undo_redo() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "={34,35,3}").unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("35".to_string()) + ); + model.undo().unwrap(); + assert_eq!(model.get_formatted_cell_value(0, 1, 2), Ok("".to_string())); + model.redo().unwrap(); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("35".to_string()) + ); +} + +#[test] +fn mixed_spills() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + // D9 => ={1,2,3} + model.set_user_input(0, 9, 4, "={34,35,3}").unwrap(); + // F6 => ={1;2;3;4} + model.set_user_input(0, 6, 6, "={1;2;3;4}").unwrap(); + + // F6 should be #SPILL! + assert_eq!( + model.get_formatted_cell_value(0, 6, 6), + Ok("#SPILL!".to_string()) + ); + + // We delete D9 + model + .range_clear_contents(&Area { + sheet: 0, + row: 9, + column: 4, + width: 1, + height: 1, + }) + .unwrap(); + + // F6 should be 1 + assert_eq!(model.get_formatted_cell_value(0, 6, 6), Ok("1".to_string())); + + // Now we undo that + model.undo().unwrap(); + // F6 should be #SPILL! + assert_eq!( + model.get_formatted_cell_value(0, 6, 6), + Ok("#SPILL!".to_string()) + ); +} + +#[test] +fn spill_order_d9_f6() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + // D9 => ={1,2,3} + model.set_user_input(0, 9, 4, "={34,35,3}").unwrap(); + // F6 => ={1;2;3;4} + model.set_user_input(0, 6, 6, "={1;2;3;4}").unwrap(); + + // F6 should be #SPILL! + assert_eq!( + model.get_formatted_cell_value(0, 6, 6), + Ok("#SPILL!".to_string()) + ); +} + +#[test] +fn spill_order_f6_d9() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + // F6 => ={1;2;3;4} + model.set_user_input(0, 6, 6, "={1;2;3;4}").unwrap(); + // D9 => ={1,2,3} + model.set_user_input(0, 9, 4, "={34,35,3}").unwrap(); + + // D9 should be #SPILL! + assert_eq!( + model.get_formatted_cell_value(0, 9, 4), + Ok("#SPILL!".to_string()) + ); +} diff --git a/base/src/types.rs b/base/src/types.rs index 3b516af..abea099 100644 --- a/base/src/types.rs +++ b/base/src/types.rs @@ -159,17 +159,17 @@ pub enum CellType { CompoundData = 128, } +/// Cell types +/// s is always the style index of the cell #[derive(Encode, Decode, Debug, Clone, PartialEq)] pub enum Cell { EmptyCell { s: i32, }, - BooleanCell { v: bool, s: i32, }, - NumberCell { v: f64, s: i32, @@ -181,6 +181,7 @@ pub enum Cell { }, // Always a shared string SharedString { + // string index si: i32, s: i32, }, @@ -189,13 +190,11 @@ pub enum Cell { f: i32, s: i32, }, - CellFormulaBoolean { f: i32, v: bool, s: i32, }, - CellFormulaNumber { f: i32, v: f64, @@ -207,9 +206,9 @@ pub enum Cell { v: String, s: i32, }, - CellFormulaError { f: i32, + // error index ei: Error, s: i32, // Origin: Sheet3!C4 @@ -217,7 +216,81 @@ pub enum Cell { // Error Message: "Not implemented function" m: String, }, - // TODO: Array formulas + // All Spill/dynamic cells have a boolean, a for array, if true it is an array formula + // Spill cells point to a mother cell (row, column) + SpillNumberCell { + v: f64, + s: i32, + // mother cell (row, column) + m: (i32, i32), + }, + SpillBooleanCell { + v: bool, + s: i32, + // mother cell (row, column) + m: (i32, i32), + }, + SpillErrorCell { + ei: Error, + s: i32, + // mother cell (row, column) + m: (i32, i32), + }, + SpillStringCell { + v: String, + s: i32, + // mother cell (row, column) + m: (i32, i32), + }, + // Dynamic cell formulas have a range (width, height) + DynamicCellFormula { + f: i32, + s: i32, + // range of the formula (width, height) + r: (i32, i32), + // true if the formula is a CSE formula + a: bool, + }, + DynamicCellFormulaBoolean { + f: i32, + v: bool, + s: i32, + // range of the formula (width, height) + r: (i32, i32), + // true if the formula is a CSE formula + a: bool, + }, + DynamicCellFormulaNumber { + f: i32, + v: f64, + s: i32, + // range of the formula (width, height) + r: (i32, i32), + // true if the formula is a CSE formula + a: bool, + }, + DynamicCellFormulaString { + f: i32, + v: String, + s: i32, + // range of the formula (width, height) + r: (i32, i32), + // true if the formula is a CSE formula + a: bool, + }, + DynamicCellFormulaError { + f: i32, + ei: Error, + s: i32, + // Cell origin of the error + o: String, + // Error message in text + m: String, + // range of the formula (width, height) + r: (i32, i32), + // true if the formula is a CSE formula + a: bool, + }, } impl Default for Cell { diff --git a/base/src/user_model/common.rs b/base/src/user_model/common.rs index 0b4b172..3e2dbb0 100644 --- a/base/src/user_model/common.rs +++ b/base/src/user_model/common.rs @@ -13,8 +13,8 @@ use crate::{ }, model::Model, types::{ - Alignment, BorderItem, CellType, Col, HorizontalAlignment, SheetProperties, SheetState, - Style, VerticalAlignment, + Alignment, BorderItem, Cell, CellType, Col, HorizontalAlignment, SheetProperties, + SheetState, Style, VerticalAlignment, }, utils::is_valid_hex_color, }; @@ -24,6 +24,18 @@ use crate::user_model::history::{ }; use super::border_utils::is_max_border; + +#[derive(Serialize, Deserialize)] +pub enum CellArrayStructure { + // It s just a single cell + SingleCell, + // It is part o a dynamic array + // (mother_row, mother_column, width, height) + DynamicChild(i32, i32, i32, i32), + // Mother of a dynamic array (width, height) + DynamicMother(i32, i32), +} + /// Data for the clipboard pub type ClipboardData = HashMap>; @@ -627,6 +639,7 @@ impl UserModel { } } self.push_diff_list(diff_list); + self.evaluate_if_not_paused(); Ok(()) } @@ -656,6 +669,7 @@ impl UserModel { } } self.push_diff_list(diff_list); + self.evaluate_if_not_paused(); Ok(()) } @@ -1595,6 +1609,65 @@ impl UserModel { Ok(self.model.workbook.worksheet(sheet)?.show_grid_lines) } + /// Returns the geometric structure of a cell + pub fn get_cell_array_structure( + &self, + sheet: u32, + row: i32, + column: i32, + ) -> Result { + let cell = self + .model + .workbook + .worksheet(sheet)? + .cell(row, column) + .cloned() + .unwrap_or_default(); + match cell { + Cell::EmptyCell { .. } + | Cell::BooleanCell { .. } + | Cell::NumberCell { .. } + | Cell::ErrorCell { .. } + | Cell::SharedString { .. } + | Cell::CellFormula { .. } + | Cell::CellFormulaBoolean { .. } + | Cell::CellFormulaNumber { .. } + | Cell::CellFormulaString { .. } + | Cell::CellFormulaError { .. } => Ok(CellArrayStructure::SingleCell), + Cell::SpillNumberCell { m, .. } + | Cell::SpillBooleanCell { m, .. } + | Cell::SpillErrorCell { m, .. } + | Cell::SpillStringCell { m, .. } => { + let (m_row, m_column) = m; + let m_cell = self + .model + .workbook + .worksheet(sheet)? + .cell(m_row, m_column) + .cloned() + .unwrap_or_default(); + let (width, height) = match m_cell { + Cell::DynamicCellFormula { r, .. } + | Cell::DynamicCellFormulaBoolean { r, .. } + | Cell::DynamicCellFormulaNumber { r, .. } + | Cell::DynamicCellFormulaString { r, .. } + | Cell::DynamicCellFormulaError { r, .. } => (r.0, r.1), + _ => return Err("Invalid structure".to_string()), + }; + Ok(CellArrayStructure::DynamicChild( + m_row, m_column, width, height, + )) + } + Cell::DynamicCellFormula { r, .. } + | Cell::DynamicCellFormulaBoolean { r, .. } + | Cell::DynamicCellFormulaNumber { r, .. } + | Cell::DynamicCellFormulaString { r, .. } + | Cell::DynamicCellFormulaError { r, .. } => { + Ok(CellArrayStructure::DynamicMother(r.0, r.1)) + } + } + } + /// Returns a copy of the selected area pub fn copy_to_clipboard(&self) -> Result { let selected_area = self.get_selected_view(); @@ -1897,6 +1970,24 @@ impl UserModel { old_value, } => { needs_evaluation = true; + let cell = self + .model + .workbook + .worksheet(*sheet)? + .cell(*row, *column) + .cloned() + .unwrap_or_default(); + if let Some((width, height)) = cell.get_dynamic_range() { + for r in *row..*row + height { + for c in *column..*column + width { + // skip the "mother" cell + if r == *row && c == *column { + continue; + } + self.model.cell_clear_contents(*sheet, r, c)?; + } + } + } match *old_value.clone() { Some(value) => { self.model diff --git a/base/src/user_model/history.rs b/base/src/user_model/history.rs index 53268e1..46b400b 100644 --- a/base/src/user_model/history.rs +++ b/base/src/user_model/history.rs @@ -5,18 +5,21 @@ use bitcode::{Decode, Encode}; use crate::types::{Cell, Col, Row, SheetState, Style, Worksheet}; #[derive(Clone, Encode, Decode)] +#[cfg_attr(debug_assertions, derive(Debug))] pub(crate) struct RowData { pub(crate) row: Option, pub(crate) data: HashMap, } #[derive(Clone, Encode, Decode)] +#[cfg_attr(debug_assertions, derive(Debug))] pub(crate) struct ColumnData { pub(crate) column: Option, pub(crate) data: HashMap, } #[derive(Clone, Encode, Decode)] +#[cfg_attr(debug_assertions, derive(Debug))] pub(crate) enum Diff { // Cell diffs SetCellValue { diff --git a/bindings/wasm/fix_types.py b/bindings/wasm/fix_types.py index fd466ee..04fe044 100644 --- a/bindings/wasm/fix_types.py +++ b/bindings/wasm/fix_types.py @@ -201,6 +201,18 @@ defined_name_list_types = r""" getDefinedNameList(): DefinedName[]; """ +cell_structure = r""" +* @returns {any} +*/ + getCellArrayStructure(sheet: number, row: number, column: number): any; +""" + +cell_structure_types = r""" +* @returns {CellArrayStructure} +*/ + getCellArrayStructure(sheet: number, row: number, column: number): CellArrayStructure; +""" + def fix_types(text): text = text.replace(get_tokens_str, get_tokens_str_types) text = text.replace(update_style_str, update_style_str_types) @@ -215,6 +227,7 @@ def fix_types(text): text = text.replace(clipboard, clipboard_types) text = text.replace(paste_from_clipboard, paste_from_clipboard_types) text = text.replace(defined_name_list, defined_name_list_types) + text = text.replace(cell_structure, cell_structure_types) with open("types.ts") as f: types_str = f.read() header_types = "{}\n\n{}".format(header, types_str) diff --git a/bindings/wasm/src/lib.rs b/bindings/wasm/src/lib.rs index 5767a2e..30d666a 100644 --- a/bindings/wasm/src/lib.rs +++ b/bindings/wasm/src/lib.rs @@ -672,4 +672,18 @@ impl Model { .delete_defined_name(name, scope) .map_err(|e| to_js_error(e.to_string())) } + + #[wasm_bindgen(js_name = "getCellArrayStructure")] + pub fn get_cell_array_structure( + &self, + sheet: u32, + row: i32, + column: i32, + ) -> Result { + let cell_structure = self + .model + .get_cell_array_structure(sheet, row, column) + .map_err(|e| to_js_error(e.to_string()))?; + serde_wasm_bindgen::to_value(&cell_structure).map_err(JsError::from) + } } diff --git a/bindings/wasm/types.ts b/bindings/wasm/types.ts index 7af55b8..fcaa2ff 100644 --- a/bindings/wasm/types.ts +++ b/bindings/wasm/types.ts @@ -109,6 +109,11 @@ export interface MarkedToken { end: number; } +export type CellArrayStructure = + | "SingleCell" + | { DynamicChild: [number, number, number, number] } + | { DynamicMother: [number, number] }; + export interface WorksheetProperties { name: string; color: string; @@ -216,7 +221,7 @@ export interface SelectedView { // }; // type ClipboardData = Record>; -type ClipboardData = Map>; +type ClipboardData = Map>; export interface ClipboardCell { text: string; @@ -233,4 +238,4 @@ export interface DefinedName { name: string; scope?: number; formula: string; -} \ No newline at end of file +} diff --git a/webapp/IronCalc/package-lock.json b/webapp/IronCalc/package-lock.json index e90e739..7d972e7 100644 --- a/webapp/IronCalc/package-lock.json +++ b/webapp/IronCalc/package-lock.json @@ -90,21 +90,21 @@ } }, "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", + "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -126,12 +126,12 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -141,12 +141,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/compat-data": "^7.26.8", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -220,24 +220,24 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -277,9 +277,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", - "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -288,28 +288,28 @@ } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -318,9 +318,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" @@ -485,9 +485,9 @@ } }, "node_modules/@chromatic-com/storybook": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.4.tgz", - "integrity": "sha512-5/bOOYxfwZ2BktXeqcCpOVAoR6UCoeART5t9FVy22hoo8F291zOuX4y3SDgm10B1GVU/ZTtJWPT2X9wZFlxYLg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.6.tgz", + "integrity": "sha512-FDmn5Ry2DzQdik+eq2sp/kJMMT36Ewe7ONXUXM2Izd97c7r6R/QyGli8eyh/F0iyqVvbLveNYFyF0dBOJNwLqw==", "dev": true, "dependencies": { "chromatic": "^11.15.0", @@ -660,9 +660,9 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", "cpu": [ "ppc64" ], @@ -676,9 +676,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", "cpu": [ "arm" ], @@ -692,9 +692,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", "cpu": [ "arm64" ], @@ -708,9 +708,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", "cpu": [ "x64" ], @@ -724,9 +724,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", "cpu": [ "arm64" ], @@ -740,9 +740,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", "cpu": [ "x64" ], @@ -756,9 +756,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", "cpu": [ "arm64" ], @@ -772,9 +772,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", "cpu": [ "x64" ], @@ -788,9 +788,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", "cpu": [ "arm" ], @@ -804,9 +804,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", "cpu": [ "arm64" ], @@ -820,9 +820,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", "cpu": [ "ia32" ], @@ -836,9 +836,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", "cpu": [ "loong64" ], @@ -852,9 +852,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", "cpu": [ "mips64el" ], @@ -868,9 +868,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", "cpu": [ "ppc64" ], @@ -884,9 +884,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", "cpu": [ "riscv64" ], @@ -900,9 +900,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", "cpu": [ "s390x" ], @@ -916,9 +916,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", "cpu": [ "x64" ], @@ -932,9 +932,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", "cpu": [ "arm64" ], @@ -948,9 +948,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", "cpu": [ "x64" ], @@ -964,9 +964,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", "cpu": [ "arm64" ], @@ -980,9 +980,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", "cpu": [ "x64" ], @@ -996,9 +996,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", "cpu": [ "x64" ], @@ -1012,9 +1012,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", "cpu": [ "arm64" ], @@ -1028,9 +1028,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", "cpu": [ "ia32" ], @@ -1044,9 +1044,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", "cpu": [ "x64" ], @@ -1173,24 +1173,24 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.5.tgz", - "integrity": "sha512-zoXvHU1YuoodgMlPS+epP084Pqv9V+Vg+5IGv9n/7IIFVQ2nkTngYHYxElCq8pdTTbDcgji+nNh0lxri2abWgA==", + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.10.tgz", + "integrity": "sha512-cblGjlM6+xsptwyaALw8RbRIUoqmKxOqLxlk2LkTDhxqUuql1YSOKKLH3w+Yd2QLz28b7MR65sx1OjsRZUfOSQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/material": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.5.tgz", - "integrity": "sha512-5eyEgSXocIeV1JkXs8mYyJXU0aFyXZIWI5kq2g/mCnIgJe594lkOBNAKnCIaGVfQTu2T6TTEHF8/hHIqpiIRGA==", + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.10.tgz", + "integrity": "sha512-L1B0+Vg9NFjo3NcfODH3bohl6fIkzjyDBHBHb3Al4QI7owaJrFm2sSDyfz++iatzICug6U6q5tHLQrCLO71xkg==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.4.5", - "@mui/system": "^6.4.3", - "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.3", + "@mui/core-downloads-tracker": "^6.4.10", + "@mui/system": "^6.4.10", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.9", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -1209,7 +1209,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.4.3", + "@mui/material-pigment-css": "^6.4.10", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1230,12 +1230,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.3.tgz", - "integrity": "sha512-7x9HaNwDCeoERc4BoEWLieuzKzXu5ZrhRnEM6AUcRXUScQLvF1NFkTlP59+IJfTbEMgcGg1wWHApyoqcksrBpQ==", + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz", + "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.3", + "@mui/utils": "^6.4.9", "prop-types": "^15.8.1" }, "engines": { @@ -1256,9 +1256,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.3.tgz", - "integrity": "sha512-OC402VfK+ra2+f12Gef8maY7Y9n7B6CZcoQ9u7mIkh/7PKwW/xH81xwX+yW+Ak1zBT3HYcVjh2X82k5cKMFGoQ==", + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.9.tgz", + "integrity": "sha512-qZRWO0cT407NI4ZRjZcH+1SOu8f3JzLHqdMlg52GyEufM9pkSZFnf7xjpwnlvkixcGjco6wLlMD0VB43KRcBuA==", "dependencies": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.5", @@ -1289,15 +1289,15 @@ } }, "node_modules/@mui/system": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.3.tgz", - "integrity": "sha512-Q0iDwnH3+xoxQ0pqVbt8hFdzhq1g2XzzR4Y5pVcICTNtoCLJmpJS3vI4y/OIM1FHFmpfmiEC2IRIq7YcZ8nsmg==", + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.10.tgz", + "integrity": "sha512-RyBGQwP3tgo4JEibK+RwVu1a6nQ6y8urMCNsb2aiN/nvTxxumq6P26aoG4GTUf8L4O1sthC4lMXlP4r8ixDkMg==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.3", - "@mui/styled-engine": "^6.4.3", - "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.3", + "@mui/private-theming": "^6.4.9", + "@mui/styled-engine": "^6.4.9", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.9", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1328,9 +1328,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.21", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", - "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1341,12 +1341,12 @@ } }, "node_modules/@mui/utils": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.3.tgz", - "integrity": "sha512-jxHRHh3BqVXE9ABxDm+Tc3wlBooYz/4XPa0+4AI+iF38rV1/+btJmSUgG4shDtSWVs/I97aDn5jBCt6SF2Uq2A==", + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz", + "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/types": "^7.2.21", + "@mui/types": "~7.2.24", "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1411,9 +1411,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", - "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz", + "integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==", "cpu": [ "arm" ], @@ -1424,9 +1424,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", - "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz", + "integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==", "cpu": [ "arm64" ], @@ -1437,9 +1437,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", - "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz", + "integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==", "cpu": [ "arm64" ], @@ -1450,9 +1450,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", - "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz", + "integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==", "cpu": [ "x64" ], @@ -1463,9 +1463,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", - "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz", + "integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==", "cpu": [ "arm64" ], @@ -1476,9 +1476,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", - "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz", + "integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==", "cpu": [ "x64" ], @@ -1489,9 +1489,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", - "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz", + "integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==", "cpu": [ "arm" ], @@ -1502,9 +1502,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", - "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz", + "integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==", "cpu": [ "arm" ], @@ -1515,9 +1515,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", - "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz", + "integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==", "cpu": [ "arm64" ], @@ -1528,9 +1528,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", - "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz", + "integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==", "cpu": [ "arm64" ], @@ -1541,9 +1541,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", - "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz", + "integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==", "cpu": [ "loong64" ], @@ -1554,9 +1554,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", - "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz", + "integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==", "cpu": [ "ppc64" ], @@ -1567,9 +1567,22 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", - "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz", + "integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz", + "integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==", "cpu": [ "riscv64" ], @@ -1580,9 +1593,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", - "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz", + "integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==", "cpu": [ "s390x" ], @@ -1593,9 +1606,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", - "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz", + "integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==", "cpu": [ "x64" ], @@ -1606,9 +1619,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", - "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz", + "integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==", "cpu": [ "x64" ], @@ -1619,9 +1632,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", - "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz", + "integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==", "cpu": [ "arm64" ], @@ -1632,9 +1645,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", - "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz", + "integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==", "cpu": [ "ia32" ], @@ -1645,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", - "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz", + "integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==", "cpu": [ "x64" ], @@ -1658,9 +1671,9 @@ ] }, "node_modules/@storybook/addon-actions": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.0.tgz", - "integrity": "sha512-lI03stcI28wN8trjp7zx0PzN1NRxSpU/551slzEhSM0tghcLxcfLZR/wh4Jp0T68Obj7z//YXPttZ9PBFajs6w==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.11.tgz", + "integrity": "sha512-7VORphqmxJf2J2a8tRgCAIeaMQ1JjYZwmwsrOwXBt77NjJbAC2qx9KecN1fsKKCyRVSk/wAICvOLStKM15+v2g==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -1674,13 +1687,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.0.tgz", - "integrity": "sha512-MbMPjuC19jJBXqQext8rENBACLKujDn+MuxIbNYMmn2ljzeYFp87tVxzlCB7XY7rV0zvkHxH8N/zDnPl7pBTcQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.11.tgz", + "integrity": "sha512-1P6qqYOQKbidV0VzYOgc7upjHqIQaFogbqm/DqNyPnwlxTIuqtzkFLiZQxMmGSQekA9SB/7ZfGglFByQXgrIUA==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -1692,13 +1705,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-controls": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.0.tgz", - "integrity": "sha512-oc+mssxmNY+D26jyJ+IZ1u8bmzveCO2wqpUl6vtLM5MruchZAHzHqa2ZIn+H9KOEqcKlYVDF5n6oEuprcnrsdg==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.11.tgz", + "integrity": "sha512-CpXu4HhiyRBikygMskmFhfgKtyz2/3BWTzpg6OrmaYuoEnxP+RMPeXZQxCW9pbH8ewGZlvX++VEt1Cletd95zQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -1710,19 +1723,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-docs": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.0.tgz", - "integrity": "sha512-ytYn5ec2Tp62t9emjXgm4Ds+eG7SiSg/vNeOwM6L1lM2UCV2/XdzntbqlUb/FHehSXIv9eRJDSe5BBzPieUUaw==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.11.tgz", + "integrity": "sha512-gTSF1m3HJkeU7GKPYhe8grO48FbpulvIWZ213PtnWedgVkTNieok3oBmmigv17ua/QXH0u5EbaoMSxaAyrsAzg==", "dev": true, "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.6.0", - "@storybook/csf-plugin": "8.6.0", - "@storybook/react-dom-shim": "8.6.0", + "@storybook/blocks": "8.6.11", + "@storybook/csf-plugin": "8.6.11", + "@storybook/react-dom-shim": "8.6.11", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -1732,24 +1745,24 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.0.tgz", - "integrity": "sha512-T3R9Q1hq6eJKy758gQgYEuAYxcddGZ8eGBLIyIJEgzpwsUnN5mF+rIqx8LoWxpWu/xiKzg17LqCBnJbLGkRZUA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.11.tgz", + "integrity": "sha512-QII5yTM0cGRryfTSJSK5Hf2CEiAX3atqccHZbPipkqO7dE9YDBvRfVwG0cQpHdv10tP066MDWgVDF5E3pDKecw==", "dev": true, "dependencies": { - "@storybook/addon-actions": "8.6.0", - "@storybook/addon-backgrounds": "8.6.0", - "@storybook/addon-controls": "8.6.0", - "@storybook/addon-docs": "8.6.0", - "@storybook/addon-highlight": "8.6.0", - "@storybook/addon-measure": "8.6.0", - "@storybook/addon-outline": "8.6.0", - "@storybook/addon-toolbars": "8.6.0", - "@storybook/addon-viewport": "8.6.0", + "@storybook/addon-actions": "8.6.11", + "@storybook/addon-backgrounds": "8.6.11", + "@storybook/addon-controls": "8.6.11", + "@storybook/addon-docs": "8.6.11", + "@storybook/addon-highlight": "8.6.11", + "@storybook/addon-measure": "8.6.11", + "@storybook/addon-outline": "8.6.11", + "@storybook/addon-toolbars": "8.6.11", + "@storybook/addon-viewport": "8.6.11", "ts-dedent": "^2.0.0" }, "funding": { @@ -1757,13 +1770,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.0.tgz", - "integrity": "sha512-xgSUzNV8ZpNDJ35bLz7wfg/q7/O/C5845wbZsn+PobUOWpOMOKeZwbGkO3Fh4+CWKeFuMhUpFiZSWkNgT+bV0g==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.11.tgz", + "integrity": "sha512-xiNIQVDj34PE6xv+V6z8dOi5HrfQYm9FE4okOOSfYcvL8p+3exAs1+13TIsDtf/c1wy8/IbU4S+H8XUExmI6qg==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -1773,18 +1786,18 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.0.tgz", - "integrity": "sha512-AgobFrUxmKgGHKeOismuLZdXlndP3ZDquHztiomfMiu01xOqNPxG0+xoCcegvftU7hKE+TlBRzhjCWg/bFz4LQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.11.tgz", + "integrity": "sha512-j9wUf8lQF922eC2HbWG4LdeflOu/togry80QB+Sqxs4+dg4iWhjxmN8gWav14/oa0vJBLN7Z2Tr4ifsJUEwRkg==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.0", - "@storybook/test": "8.6.0", + "@storybook/instrumenter": "8.6.11", + "@storybook/test": "8.6.11", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -1793,13 +1806,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-measure": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.0.tgz", - "integrity": "sha512-ogc+VNLyXq8hGfI4Fkmh9i3JbxfiIViiINdBoldD6K0gId3yaqqrSwQ2vWhYIbfUuz+PsMxsoNS7MD4EiRXhPg==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.11.tgz", + "integrity": "sha512-9Y0qXF9WEg4WHszT17FhppHXcRLv+XC+kpLiKYiL2D4Cm1Xz/2s0N1J50dLBL/gHW04jrVk5lPlpJbcJgWBE5Q==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -1810,13 +1823,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-outline": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.0.tgz", - "integrity": "sha512-IWxrNNZOk5rtOdnLNyK7gpqi0g0rMGYl5ju37Glbfa7iG2J1VKofG2CbkUpVyVY0uiTXqkKkhOKlc9zELhLQSg==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.11.tgz", + "integrity": "sha512-LddoqoWYQArzxFXEGL2omJFRCfYn6/F+4IkPuQC+S7wZrwBw89riVPKjL8EmAZ62pEByhJHabUD8ZXTVTqpMlg==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -1827,26 +1840,26 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.0.tgz", - "integrity": "sha512-Mg0V9RrnDt/IQe+zjggGS+4Otkv4YFqyjL/ygwnV6aKGgzL5zFpC+5rf8MeBEvNeol9+THC/XltN/Xf+jbtLEQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.11.tgz", + "integrity": "sha512-5ImZfjXisBhYWPoxjYr08nucCF6wqq1a81nWdSnHaB1xFKJZAKtp3GiF7Hyp8B0+olMk1OgSJXEXlXZ1ZbK5Vg==", "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.0.tgz", - "integrity": "sha512-sVDF3gIjGdvfBdCM/jEBu6Nd5GlqITKBtdySiQdNDl5JI4ak77ZM+T+VQmJxB4sIqvCjWzCbQqUC45nymVObug==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.11.tgz", + "integrity": "sha512-EdzrkUyMvm0epYkUspBF5osU0rIHglD1+YK84C8ibJjx3JpnpLFaDpecwjFaFgxjQQVveHKatYcHpz09aEywqQ==", "dev": true, "dependencies": { "memoizerific": "^1.11.3" @@ -1856,13 +1869,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/blocks": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.0.tgz", - "integrity": "sha512-3PNxlB5Ooj8CIhttbDxeV6kW7ui+2GEdTngtqhnsUHVjzeTKpilsk2lviOeUzqlyq5FDK+rhpZ3L3DJ9pDvioA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.11.tgz", + "integrity": "sha512-2IyS3nB6SoEjIt0nWUMxtRIjJRUvDU8EF/eMbM4F/FuwIM402P3kNQ4n4+q1xZtYjvoMr5QUq+K8YF4ZlxIz0A==", "dev": true, "dependencies": { "@storybook/icons": "^1.2.12", @@ -1875,7 +1888,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^8.6.0" + "storybook": "^8.6.11" }, "peerDependenciesMeta": { "react": { @@ -1887,12 +1900,12 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.0.tgz", - "integrity": "sha512-Bdc5fXLJbPdQo2eJ3dDNhfhWuQOME2KWvrixnsfo57IOhDa5B81jVcDBQIIgB9K1NQDRGyaWfYCcKZqy16yPlQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.11.tgz", + "integrity": "sha512-d8SsHr6iM49kTyrg6PTYn9aHxOBiWUZvPhOOtfODHl2SH9PPRenfwX3a3B+OsD04GPVGvLz5fp4Apg9lrDVSzw==", "dev": true, "dependencies": { - "@storybook/csf-plugin": "8.6.0", + "@storybook/csf-plugin": "8.6.11", "browser-assert": "^1.2.1", "ts-dedent": "^2.0.0" }, @@ -1901,14 +1914,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0", + "storybook": "^8.6.11", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@storybook/components": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.0.tgz", - "integrity": "sha512-k5MQAuLPt5KOaa5J4QvX/WKucaiFTMJiEX5lsSaY6qON6Sx8PtnLQxVwWF7BIMW/jLpd94BUxrVjVrQKlwoLKQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.11.tgz", + "integrity": "sha512-+lHcwQsSO8usKTXIBBmgmRCAa0L+KQaLJ5ARqkRTm6OjzkVVS+EPnIgL4H1nqzbwiTVXxSSOwAk+rST83KICnA==", "dev": true, "funding": { "type": "opencollective", @@ -1919,12 +1932,12 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.0.tgz", - "integrity": "sha512-UzVo2sNz8PZuDp++/R9NBtjupSXhvxS8lptYcwtk51b6MvcM4AL/b4V3PGryOVJDru9sMwz+pzaj7Jg8RVFMJA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.11.tgz", + "integrity": "sha512-fhzLQ9HpljbLpkHykafmcjIERHI5j6SZhylFCDwEWkETuZtRbyCs3mmULutcEOzKhxRgNtiIRoRmZPdQcPtHNg==", "dev": true, "dependencies": { - "@storybook/theming": "8.6.0", + "@storybook/theming": "8.6.11", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -1962,9 +1975,9 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.0.tgz", - "integrity": "sha512-Cd7LL4XQ8ccUDzJGxVyuzgsYuRYS5LVL4/ZNmAxikz9LtVrVFI/4RgFa5MvlQZc0twreoLtztFskziny8OiJUQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.11.tgz", + "integrity": "sha512-NC/o+SSjSC29hcQrPNoLCDRkqRTagkcAgFf0xEybX3mkLT0q+w3ZHJg1HQz7TtaigIzZ06iIPncif2xKvYgETw==", "dev": true, "dependencies": { "unplugin": "^1.3.1" @@ -1974,7 +1987,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/global": { @@ -1984,9 +1997,9 @@ "dev": true }, "node_modules/@storybook/icons": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.3.2.tgz", - "integrity": "sha512-t3xcbCKkPvqyef8urBM0j/nP6sKtnlRkVgC+8JTbTAZQjaTmOjes3byEgzs89p4B/K6cJsg9wLW2k3SknLtYJw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.4.0.tgz", + "integrity": "sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA==", "dev": true, "engines": { "node": ">=14.0.0" @@ -1997,9 +2010,9 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.0.tgz", - "integrity": "sha512-eEY/Hfa3Vj5Nv4vHRHlSqjoyW6oAKNK3rKIXfL/eawQwb7rKhzijDLG5YBH44Hh7dEPIqUp0LEdgpyIY7GXezg==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.11.tgz", + "integrity": "sha512-IOLvc4BOVKofWhyRScA2h/R36cACBK3DUCrZkQTLU+FUIXWg7Yjyco7lDEk/0W9mlH0Fe/eWEhluI2WTowkesQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -2010,13 +2023,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/manager-api": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.0.tgz", - "integrity": "sha512-ddBibYrO3yQCdtZBqQYqfABjR9eS+llvt2NFDajfyQw+zmuNIZfw4BDGKH1WHE4wm/kXmlFFhPHXaHgAPTRPfQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.11.tgz", + "integrity": "sha512-U3ijEFX7B7wNYzFctmTIXOiN0zLlt8/9EHbZQUUrQ1pf7bQzADJCy63Y3B+kir8i+n3LsBWB42X2aSiT0lLaKQ==", "dev": true, "funding": { "type": "opencollective", @@ -2027,9 +2040,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.0.tgz", - "integrity": "sha512-c/sZj4Tb+DtdCndcjoFUneUwl2XUdQckqN4nf1SuIJ/BXRbAexlD04fvPJ4wzmwUNg8EQF7BhTWVNDa1RvJz2w==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.11.tgz", + "integrity": "sha512-NpSVJFa9MkPq3u/h+bvx+iSnm6OG6mMUzMgmY67mA0dgIgOWcaoP2Y7254SZlBeho97HCValTDKJyqZMwiVlyQ==", "dev": true, "funding": { "type": "opencollective", @@ -2040,17 +2053,17 @@ } }, "node_modules/@storybook/react": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.0.tgz", - "integrity": "sha512-go0KhCFcOhxkTdaMCxeuJxmc/5CaiaO76+SBzIoPIMWEh9tZQmKb+vojdKcFZswHjZV3zA1uJFUzyympspRffA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.11.tgz", + "integrity": "sha512-ZaE2IS5alauWxEvWo8LNEi27QxiRfJrfffDpQJIIvY4WnR+jzgLdtMOAVo/cSM9mJSRLESEYW57b0l7JdQGm1g==", "dev": true, "dependencies": { - "@storybook/components": "8.6.0", + "@storybook/components": "8.6.11", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.6.0", - "@storybook/preview-api": "8.6.0", - "@storybook/react-dom-shim": "8.6.0", - "@storybook/theming": "8.6.0" + "@storybook/manager-api": "8.6.11", + "@storybook/preview-api": "8.6.11", + "@storybook/react-dom-shim": "8.6.11", + "@storybook/theming": "8.6.11" }, "engines": { "node": ">=18.0.0" @@ -2060,10 +2073,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.0", + "@storybook/test": "8.6.11", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0", + "storybook": "^8.6.11", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -2076,9 +2089,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.0.tgz", - "integrity": "sha512-5Y+vMHhcx0xnaNsLQMbkmjc3zkDn/fGBNsiLH2e4POvW3ZQvOxjoyxAsEQaKwLtFgsdCFSd2tR89F6ItYrA2JQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.11.tgz", + "integrity": "sha512-giwqwx0PO70SyqoZ25CBM2tpAjJX5sjPm7uWKknYcFGl3H2PYDqqnvH7NfEXENQMq5DpAJisCZ0KkRvNHzLV2w==", "dev": true, "funding": { "type": "opencollective", @@ -2087,19 +2100,19 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/react-vite": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.0.tgz", - "integrity": "sha512-uDQyf2u0Zki4qIavOu2jyGIlvmUOsgCpHXY+7KHr542ZIkXI3mGOi5/rwUxgNSHGD3JloYGdlt+4Md+9i5xEbA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.11.tgz", + "integrity": "sha512-UjAIzmfmZIhrMB5MYrc4RswTca0oodbG8m3iBBCadjy+rSZ/c9cbZgkI3bU8W5khkCToQoAXNJI8xWYfr/PGxw==", "dev": true, "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.5.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "8.6.0", - "@storybook/react": "8.6.0", + "@storybook/builder-vite": "8.6.11", + "@storybook/react": "8.6.11", "find-up": "^5.0.0", "magic-string": "^0.30.0", "react-docgen": "^7.0.0", @@ -2114,10 +2127,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.0", + "@storybook/test": "8.6.11", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.0", + "storybook": "^8.6.11", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { @@ -2127,13 +2140,13 @@ } }, "node_modules/@storybook/test": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.0.tgz", - "integrity": "sha512-qiiv4wh4FoxTb1PoiA/noo9HcLDqfTwL0svMoNpTy2Bxm6xajgg5zYmmIT4pKyQkMd9pfKKQKILok31VxAj8vw==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.11.tgz", + "integrity": "sha512-bk8JCRmVRHjnyt+/YnzCMEd4Y/K2L3uM+sCNuH4pYw6XT2UkR3Dj5mScGnfMvm98lHfpZDcD/AbY2vorOQsq+g==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.0", + "@storybook/instrumenter": "8.6.11", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -2145,13 +2158,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.0" + "storybook": "^8.6.11" } }, "node_modules/@storybook/theming": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.0.tgz", - "integrity": "sha512-te7dl0ZXnEyKS4LW+QHc3MP7nurWhWhmClY7G2WKNW9eHenb9zvXkcAQt6c4OWhrJi01CAYoXmZNJP0jEzxRRQ==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.11.tgz", + "integrity": "sha512-G7IK5P9gzofUjfYhMo9Pdgbqcr22eoKFLD808Q8RxJopDoypdZKg4tes2iD+6YnrtnHS0nEoP/soMmfFYl9FIw==", "dev": true, "funding": { "type": "opencollective", @@ -2534,9 +2547,9 @@ } }, "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==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -2549,9 +2562,9 @@ "dev": true }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true }, "node_modules/@types/mdx": { @@ -2561,9 +2574,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.13.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", - "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "version": "22.13.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz", + "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", "dev": true, "peer": true, "dependencies": { @@ -2581,9 +2594,9 @@ "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "node_modules/@types/react": { - "version": "19.0.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", - "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "version": "19.0.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz", + "integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==", "peer": true, "dependencies": { "csstype": "^3.0.2" @@ -2680,12 +2693,12 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.7.tgz", - "integrity": "sha512-qui+3BLz9Eonx4EAuR/i+QlCX6AUZ35taDQgwGkK/Tw6/WgwodSrjN1X2xf69IA/643ZX5zNKIn2svvtZDrs4w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz", + "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==", "dev": true, "dependencies": { - "@vitest/spy": "3.0.7", + "@vitest/spy": "3.1.1", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -2706,9 +2719,9 @@ } }, "node_modules/@vitest/mocker/node_modules/@vitest/spy": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.7.tgz", - "integrity": "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz", + "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==", "dev": true, "dependencies": { "tinyspy": "^3.0.2" @@ -2739,12 +2752,12 @@ } }, "node_modules/@vitest/runner": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.7.tgz", - "integrity": "sha512-WeEl38Z0S2ZcuRTeyYqaZtm4e26tq6ZFqh5y8YD9YxfWuu0OFiGFUbnxNynwLjNRHPsXyee2M9tV7YxOTPZl2g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz", + "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==", "dev": true, "dependencies": { - "@vitest/utils": "3.0.7", + "@vitest/utils": "3.1.1", "pathe": "^2.0.3" }, "funding": { @@ -2752,9 +2765,9 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz", - "integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz", + "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", "dev": true, "dependencies": { "tinyrainbow": "^2.0.0" @@ -2764,12 +2777,12 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/utils": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.7.tgz", - "integrity": "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz", + "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==", "dev": true, "dependencies": { - "@vitest/pretty-format": "3.0.7", + "@vitest/pretty-format": "3.1.1", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" }, @@ -2787,12 +2800,12 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.7.tgz", - "integrity": "sha512-eqTUryJWQN0Rtf5yqCGTQWsCFOQe4eNz5Twsu21xYEcnFJtMU5XvmG0vgebhdLlrHQTSq5p8vWHJIeJQV8ovsA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz", + "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==", "dev": true, "dependencies": { - "@vitest/pretty-format": "3.0.7", + "@vitest/pretty-format": "3.1.1", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -2801,9 +2814,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz", - "integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz", + "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", "dev": true, "dependencies": { "tinyrainbow": "^2.0.0" @@ -2848,9 +2861,9 @@ } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3072,13 +3085,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -3108,9 +3121,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001700", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", - "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", "dev": true, "funding": [ { @@ -3169,9 +3182,9 @@ } }, "node_modules/chromatic": { - "version": "11.26.0", - "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.26.0.tgz", - "integrity": "sha512-3rRiPmdnt5sbYZTlr6Uqd11S/teafQA1Dr6mCddIz/FFKYPv/Yt26nJllixyFd9VUwrILMPTyuracUIgJ77VZA==", + "version": "11.27.0", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.27.0.tgz", + "integrity": "sha512-jQ2ufjS+ePpg+NtcPI9B2eOi+pAzlRd2nhd1LgNMsVCC9Bzf5t8mJtyd8v2AUuJS0LdX0QVBgkOnlNv9xviHzA==", "dev": true, "bin": { "chroma": "dist/bin.js", @@ -3403,9 +3416,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.104", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.104.tgz", - "integrity": "sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g==", + "version": "1.5.129", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz", + "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==", "dev": true }, "node_modules/emoji-regex": { @@ -3471,9 +3484,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -3483,31 +3496,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" } }, "node_modules/esbuild-register": { @@ -3571,9 +3584,9 @@ } }, "node_modules/expect-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", - "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", + "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", "dev": true, "engines": { "node": ">=12.0.0" @@ -4273,9 +4286,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -4586,9 +4599,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", - "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "engines": { "node": ">=0.10.0" } @@ -4603,9 +4616,9 @@ } }, "node_modules/react-confetti": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.2.3.tgz", - "integrity": "sha512-Jt6Fy3jE7FrpKxeDQ3oh36Bz6LoYt4o+vU578ghuF//NxADlcauDYvWr24S8hHKnQ90Uv01XXOngnKVBdZ73zQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.4.0.tgz", + "integrity": "sha512-5MdGUcqxrTU26I2EU7ltkWPwxvucQTuqMm8dUz72z2YMqTD6s9vMcDUysk7n9jnC+lXuCPeJJ7Knf98VEYE9Rg==", "dev": true, "dependencies": { "tween-functions": "^1.2.0" @@ -4648,14 +4661,14 @@ } }, "node_modules/react-dom": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", - "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "dependencies": { - "scheduler": "^0.25.0" + "scheduler": "^0.26.0" }, "peerDependencies": { - "react": "^19.0.0" + "react": "^19.1.0" } }, "node_modules/react-i18next": { @@ -4680,9 +4693,9 @@ } }, "node_modules/react-is": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", - "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==" }, "node_modules/react-refresh": { "version": "0.14.2", @@ -4709,9 +4722,9 @@ } }, "node_modules/recast": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", "dev": true, "dependencies": { "ast-types": "^0.16.1", @@ -4791,12 +4804,12 @@ } }, "node_modules/rollup": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", - "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz", + "integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==", "dev": true, "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.7" }, "bin": { "rollup": "dist/bin/rollup" @@ -4806,25 +4819,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.8", - "@rollup/rollup-android-arm64": "4.34.8", - "@rollup/rollup-darwin-arm64": "4.34.8", - "@rollup/rollup-darwin-x64": "4.34.8", - "@rollup/rollup-freebsd-arm64": "4.34.8", - "@rollup/rollup-freebsd-x64": "4.34.8", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", - "@rollup/rollup-linux-arm-musleabihf": "4.34.8", - "@rollup/rollup-linux-arm64-gnu": "4.34.8", - "@rollup/rollup-linux-arm64-musl": "4.34.8", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", - "@rollup/rollup-linux-riscv64-gnu": "4.34.8", - "@rollup/rollup-linux-s390x-gnu": "4.34.8", - "@rollup/rollup-linux-x64-gnu": "4.34.8", - "@rollup/rollup-linux-x64-musl": "4.34.8", - "@rollup/rollup-win32-arm64-msvc": "4.34.8", - "@rollup/rollup-win32-ia32-msvc": "4.34.8", - "@rollup/rollup-win32-x64-msvc": "4.34.8", + "@rollup/rollup-android-arm-eabi": "4.38.0", + "@rollup/rollup-android-arm64": "4.38.0", + "@rollup/rollup-darwin-arm64": "4.38.0", + "@rollup/rollup-darwin-x64": "4.38.0", + "@rollup/rollup-freebsd-arm64": "4.38.0", + "@rollup/rollup-freebsd-x64": "4.38.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.38.0", + "@rollup/rollup-linux-arm-musleabihf": "4.38.0", + "@rollup/rollup-linux-arm64-gnu": "4.38.0", + "@rollup/rollup-linux-arm64-musl": "4.38.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.38.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.38.0", + "@rollup/rollup-linux-riscv64-gnu": "4.38.0", + "@rollup/rollup-linux-riscv64-musl": "4.38.0", + "@rollup/rollup-linux-s390x-gnu": "4.38.0", + "@rollup/rollup-linux-x64-gnu": "4.38.0", + "@rollup/rollup-linux-x64-musl": "4.38.0", + "@rollup/rollup-win32-arm64-msvc": "4.38.0", + "@rollup/rollup-win32-ia32-msvc": "4.38.0", + "@rollup/rollup-win32-x64-msvc": "4.38.0", "fsevents": "~2.3.2" } }, @@ -4846,9 +4860,9 @@ } }, "node_modules/scheduler": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", - "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==" + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" }, "node_modules/semver": { "version": "6.3.1", @@ -4949,18 +4963,18 @@ "dev": true }, "node_modules/std-env": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", - "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", "dev": true }, "node_modules/storybook": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.0.tgz", - "integrity": "sha512-NEHCK2nXogw7WxAkJfMwPnc5Cmh/KqVNrdaFeXBAKhC2Zr1FTZIiCR5nSUT85run44Wkpmo7qvUoKvII9GOWbA==", + "version": "8.6.11", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.11.tgz", + "integrity": "sha512-B2wxpmq1QYS4JV7RQu1mOHD7akfoGbuoUSkx2D2GZgv/zXAHZmDpSFcTvvBBm8FAtzChI9HhITSJ0YS0ePfnJQ==", "dev": true, "dependencies": { - "@storybook/core": "8.6.0" + "@storybook/core": "8.6.11" }, "bin": { "getstorybook": "bin/index.cjs", @@ -5294,9 +5308,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -5356,9 +5370,9 @@ "dev": true }, "node_modules/vite": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", - "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", + "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", "dev": true, "dependencies": { "esbuild": "^0.25.0", @@ -5427,9 +5441,9 @@ } }, "node_modules/vite-node": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.7.tgz", - "integrity": "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz", + "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -5463,30 +5477,30 @@ } }, "node_modules/vitest": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.7.tgz", - "integrity": "sha512-IP7gPK3LS3Fvn44x30X1dM9vtawm0aesAa2yBIZ9vQf+qB69NXC5776+Qmcr7ohUXIQuLhk7xQR0aSUIDPqavg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz", + "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==", "dev": true, "dependencies": { - "@vitest/expect": "3.0.7", - "@vitest/mocker": "3.0.7", - "@vitest/pretty-format": "^3.0.7", - "@vitest/runner": "3.0.7", - "@vitest/snapshot": "3.0.7", - "@vitest/spy": "3.0.7", - "@vitest/utils": "3.0.7", + "@vitest/expect": "3.1.1", + "@vitest/mocker": "3.1.1", + "@vitest/pretty-format": "^3.1.1", + "@vitest/runner": "3.1.1", + "@vitest/snapshot": "3.1.1", + "@vitest/spy": "3.1.1", + "@vitest/utils": "3.1.1", "chai": "^5.2.0", "debug": "^4.4.0", - "expect-type": "^1.1.0", + "expect-type": "^1.2.0", "magic-string": "^0.30.17", "pathe": "^2.0.3", - "std-env": "^3.8.0", + "std-env": "^3.8.1", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.0.7", + "vite-node": "3.1.1", "why-is-node-running": "^2.3.0" }, "bin": { @@ -5502,8 +5516,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.0.7", - "@vitest/ui": "3.0.7", + "@vitest/browser": "3.1.1", + "@vitest/ui": "3.1.1", "happy-dom": "*", "jsdom": "*" }, @@ -5532,13 +5546,13 @@ } }, "node_modules/vitest/node_modules/@vitest/expect": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.7.tgz", - "integrity": "sha512-QP25f+YJhzPfHrHfYHtvRn+uvkCFCqFtW9CktfBxmB+25QqWsx7VB2As6f4GmwllHLDhXNHvqedwhvMmSnNmjw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz", + "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==", "dev": true, "dependencies": { - "@vitest/spy": "3.0.7", - "@vitest/utils": "3.0.7", + "@vitest/spy": "3.1.1", + "@vitest/utils": "3.1.1", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -5547,9 +5561,9 @@ } }, "node_modules/vitest/node_modules/@vitest/pretty-format": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz", - "integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz", + "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", "dev": true, "dependencies": { "tinyrainbow": "^2.0.0" @@ -5559,9 +5573,9 @@ } }, "node_modules/vitest/node_modules/@vitest/spy": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.7.tgz", - "integrity": "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz", + "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==", "dev": true, "dependencies": { "tinyspy": "^3.0.2" @@ -5571,12 +5585,12 @@ } }, "node_modules/vitest/node_modules/@vitest/utils": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.7.tgz", - "integrity": "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz", + "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==", "dev": true, "dependencies": { - "@vitest/pretty-format": "3.0.7", + "@vitest/pretty-format": "3.1.1", "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" }, @@ -5623,15 +5637,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, @@ -5765,9 +5780,9 @@ "dev": true }, "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", "dev": true, "optional": true, "peer": true, diff --git a/webapp/IronCalc/src/components/FormulaBar/FormulaBar.tsx b/webapp/IronCalc/src/components/FormulaBar/FormulaBar.tsx index df1bfbb..5c52add 100644 --- a/webapp/IronCalc/src/components/FormulaBar/FormulaBar.tsx +++ b/webapp/IronCalc/src/components/FormulaBar/FormulaBar.tsx @@ -13,6 +13,7 @@ import type { WorkbookState } from "../workbookState"; type FormulaBarProps = { cellAddress: string; formulaValue: string; + isPartOfArray: boolean; model: Model; workbookState: WorkbookState; onChange: () => void; @@ -23,6 +24,7 @@ function FormulaBar(properties: FormulaBarProps) { const { cellAddress, formulaValue, + isPartOfArray, model, onChange, onTextUpdated, @@ -62,6 +64,9 @@ function FormulaBar(properties: FormulaBarProps) { event.stopPropagation(); event.preventDefault(); }} + sx={{ + color: isPartOfArray ? "grey" : "black", + }} > { return model.getCellContent(sheet, row, column); }; + // returns true if it is either single cell or the root cell of an array + const isRootCellOfArray = () => { + const { sheet, row, column } = model.getSelectedView(); + const r = model.getCellArrayStructure(sheet, row, column); + if (r === "SingleCell") { + return false; + } + if ("DynamicMother" in r) { + return false; + } + return true; + }; + const getCellStyle = useCallback(() => { const { sheet, row, column } = model.getSelectedView(); return model.getCellStyle(sheet, row, column); @@ -698,6 +711,7 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => { }} model={model} workbookState={workbookState} + isPartOfArray={isRootCellOfArray()} /> (null); const areaOutline = useRef(null); const cellOutlineHandle = useRef(null); + const cellArrayStructure = useRef(null); const extendToOutline = useRef(null); const columnResizeGuide = useRef(null); const rowResizeGuide = useRef(null); @@ -87,6 +89,7 @@ const Worksheet = forwardRef( const outline = cellOutline.current; const handle = cellOutlineHandle.current; const area = areaOutline.current; + const arrayStructure = cellArrayStructure.current; const extendTo = extendToOutline.current; const editor = editorElement.current; @@ -101,7 +104,8 @@ const Worksheet = forwardRef( !area || !extendTo || !scrollElement.current || - !editor + !editor || + !arrayStructure ) return; // FIXME: This two need to be computed. @@ -119,6 +123,7 @@ const Worksheet = forwardRef( columnHeaders: columnHeadersRef, cellOutline: outline, cellOutlineHandle: handle, + cellArrayStructure: arrayStructure, areaOutline: area, extendToOutline: extendTo, editor: editor, @@ -462,6 +467,7 @@ const Worksheet = forwardRef( /> +