В разы улучшена производительность и меьнше багов

This commit is contained in:
2025-07-15 18:11:02 +03:00
parent 40145206b2
commit 75141f5e88
5 changed files with 666 additions and 276 deletions

View File

@@ -22,6 +22,7 @@
"@radix-ui/react-toast": "^1.2.14", "@radix-ui/react-toast": "^1.2.14",
"@reduxjs/toolkit": "^1.9.5", "@reduxjs/toolkit": "^1.9.5",
"@types/react-grid-layout": "^1.3.5", "@types/react-grid-layout": "^1.3.5",
"@types/react-window": "^1.8.8",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"immer": "^10.1.1", "immer": "^10.1.1",
@@ -30,6 +31,7 @@
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-grid-layout": "^1.5.2", "react-grid-layout": "^1.5.2",
"react-window": "^1.8.11",
"redux": "^4.2.1", "redux": "^4.2.1",
"tailwind-merge": "^3.3.1", "tailwind-merge": "^3.3.1",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"

View File

@@ -1,5 +1,6 @@
import { produce } from 'immer' import { produce } from 'immer'
import { import {
CSSProperties,
FC, FC,
memo, memo,
useCallback, useCallback,
@@ -8,6 +9,7 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import { VariableSizeGrid } from 'react-window'
import { useMultiSheetEngine } from '../../hooks/useMultiSheetEngine' import { useMultiSheetEngine } from '../../hooks/useMultiSheetEngine'
const ROW_COUNT = 90 const ROW_COUNT = 90
@@ -29,6 +31,14 @@ interface DualSpreadsheetProps {
templateData?: Record<string, Record<string, any>> templateData?: Record<string, Record<string, any>>
} }
// Кэшированные данные ячеек для оптимизации
interface CachedCellData {
displayValue: string
rawValue: string
isModified: boolean
hasRightContent: boolean
}
// --- Child Components --- // --- Child Components ---
interface CellProps { interface CellProps {
sheetType: SheetType sheetType: SheetType
@@ -40,12 +50,14 @@ interface CellProps {
displayValue: string // Отображаемое значение (вычисленное) displayValue: string // Отображаемое значение (вычисленное)
rawValue: string // "Сырое" значение (формула) rawValue: string // "Сырое" значение (формула)
isModified: boolean isModified: boolean
hasRightContent: boolean // Есть ли содержимое в ячейках справа
onCellClick: (row: number, col: number) => void onCellClick: (row: number, col: number) => void
onCellDoubleClick: (row: number, col: number) => void onCellDoubleClick: (row: number, col: number) => void
onCellValueChange: (newValue: string) => void // Изменение значения во время редактирования onCellValueChange: (newValue: string) => void // Изменение значения во время редактирования
stopEditing: (save: boolean) => void stopEditing: (save: boolean) => void
setActiveSheet: (type: SheetType) => void setActiveSheet: (type: SheetType) => void
activeCellRef: React.RefObject<HTMLInputElement> activeCellRef: React.RefObject<HTMLInputElement>
style: CSSProperties // Добавляем style для react-window
} }
const Cell = memo( const Cell = memo(
@@ -59,24 +71,23 @@ const Cell = memo(
displayValue, displayValue,
rawValue, rawValue,
isModified, isModified,
hasRightContent,
onCellClick, onCellClick,
onCellDoubleClick, onCellDoubleClick,
onCellValueChange, onCellValueChange,
stopEditing, stopEditing,
setActiveSheet, setActiveSheet,
activeCellRef, activeCellRef,
style, // Добавляем style для react-window
}: CellProps) => { }: CellProps) => {
const className = `border border-border ${isSelected ? 'bg-accent' : ''} ${ const className = `border border-border ${isSelected ? 'bg-accent' : ''} ${
isModified ? 'bg-yellow-50' : '' isModified ? 'bg-yellow-50' : ''
}` }`
const style = { const cellStyle: CSSProperties = {
minWidth: `${columnWidth}px`, ...style,
width: `${columnWidth}px`, overflow: 'visible',
height: `${ROW_HEIGHT}px`,
overflow: 'hidden',
padding: 0, padding: 0,
position: 'relative' as const,
} }
const handleClick = useCallback(() => { const handleClick = useCallback(() => {
@@ -90,9 +101,9 @@ const Cell = memo(
) )
return ( return (
<td <div
className={className} className={className}
style={style} style={cellStyle}
onClick={handleClick} onClick={handleClick}
onDoubleClick={handleDoubleClick} onDoubleClick={handleDoubleClick}
> >
@@ -116,17 +127,29 @@ const Cell = memo(
/> />
) : ( ) : (
<div <div
className="relative h-full w-full truncate px-2 py-1" className="relative flex h-full w-full items-center px-2"
style={ style={{
isSelected overflow: hasRightContent ? 'hidden' : 'visible',
whiteSpace: 'nowrap',
...(isSelected
? { boxShadow: 'inset 0 0 0 2px hsl(var(--primary))' } ? { boxShadow: 'inset 0 0 0 2px hsl(var(--primary))' }
: {} : {}),
} }}
>
<div
className="relative"
style={{
overflow: hasRightContent ? 'hidden' : 'visible',
textOverflow: hasRightContent ? 'ellipsis' : 'clip',
whiteSpace: 'nowrap',
maxWidth: hasRightContent ? `${columnWidth - 16}px` : 'none',
}}
> >
{displayValue} {displayValue}
</div> </div>
</div>
)} )}
</td> </div>
) )
}, },
) )
@@ -236,15 +259,82 @@ const FormulaBar = memo(
}, },
) )
// Рендер-проп для ячеек грида
const CellRenderer = ({
columnIndex,
rowIndex,
style,
data,
}: {
columnIndex: number
rowIndex: number
style: CSSProperties
data: any
}) => {
const {
sheetType,
widths,
selectedCell,
activeSheet,
isEditing,
editingValue,
cachedData,
handleCellClick,
handleCellDoubleClick,
handleCellChange,
stopEditing,
setActiveSheet,
activeCellInputRef,
} = data
const isCellSelected =
selectedCell?.row === rowIndex &&
selectedCell?.col === columnIndex &&
activeSheet === sheetType
const isCellEditing = isCellSelected && isEditing
const cellKey = `${rowIndex}-${columnIndex}`
const cellData = cachedData[cellKey]
const rawValue = isCellEditing ? editingValue : cellData?.rawValue || ''
const displayValue = isCellEditing
? '' // Не показывать вычисленное значение во время редактирования
: cellData?.displayValue || ''
return (
<Cell
style={style}
sheetType={sheetType}
rowIndex={rowIndex}
colIndex={columnIndex}
columnWidth={widths[columnIndex]}
isSelected={isCellSelected}
isEditing={isCellEditing}
displayValue={displayValue}
rawValue={rawValue}
isModified={cellData?.isModified || false}
hasRightContent={cellData?.hasRightContent || false}
onCellClick={handleCellClick}
onCellDoubleClick={handleCellDoubleClick}
onCellValueChange={handleCellChange}
stopEditing={stopEditing}
setActiveSheet={setActiveSheet}
activeCellRef={activeCellInputRef}
/>
)
}
// --- Main Component --- // --- Main Component ---
const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => { const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
const { revision, ...multiSheetEngine } = useMultiSheetEngine({ const { revision, updateRevision, ...multiSheetEngine } = useMultiSheetEngine(
{
sheets: [ sheets: [
{ name: SHEET_NAMES.report, rows: ROW_COUNT, cols: COL_COUNT }, { name: SHEET_NAMES.report, rows: ROW_COUNT, cols: COL_COUNT },
{ name: SHEET_NAMES.calculations, rows: ROW_COUNT, cols: COL_COUNT }, { name: SHEET_NAMES.calculations, rows: ROW_COUNT, cols: COL_COUNT },
], ],
initialData: templateData || {}, initialData: templateData || {},
}) },
)
const [activeSheet, setActiveSheet] = useState<SheetType>('report') const [activeSheet, setActiveSheet] = useState<SheetType>('report')
const [selectedCell, setSelectedCell] = useState<{ const [selectedCell, setSelectedCell] = useState<{
@@ -260,6 +350,10 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
calculations: Array(COL_COUNT).fill(96), calculations: Array(COL_COUNT).fill(96),
}), }),
) )
const gridRefs = useRef<Record<SheetType, VariableSizeGrid | null>>({
report: null,
calculations: null,
})
const containerRefs = useRef<Record<SheetType, HTMLDivElement | null>>({ const containerRefs = useRef<Record<SheetType, HTMLDivElement | null>>({
report: null, report: null,
@@ -270,8 +364,22 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
report: null, report: null,
calculations: null, calculations: null,
}) })
const headerRefs = useRef<Record<SheetType, HTMLDivElement | null>>({
report: null,
calculations: null,
})
const rowHeaderRefs = useRef<Record<SheetType, HTMLDivElement | null>>({
report: null,
calculations: null,
})
const initialTemplateValues = useRef<Record<string, string>>({}) const initialTemplateValues = useRef<Record<string, string>>({})
// Кэш для данных ячеек
const cellDataCache = useRef<Record<string, Record<string, CachedCellData>>>(
{},
)
const lastRevision = useRef<number>(-1)
// Загрузка данных шаблона один раз при инициализации // Загрузка данных шаблона один раз при инициализации
useEffect(() => { useEffect(() => {
const reportTemplate = templateData?.[SHEET_NAMES.report] const reportTemplate = templateData?.[SHEET_NAMES.report]
@@ -284,6 +392,95 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
// --- Синхронизация UI --- // --- Синхронизация UI ---
// Синхронизация прокрутки грида при изменении выделенной ячейки
useEffect(() => {
if (selectedCell && activeSheet) {
const grid = gridRefs.current[activeSheet]
grid?.scrollToItem({
rowIndex: selectedCell.row,
columnIndex: selectedCell.col,
align: 'auto',
})
}
}, [selectedCell, activeSheet])
// Функция для получения кэшированных данных ячеек
const getCachedCellData = useCallback(
(sheetType: SheetType): Record<string, CachedCellData> => {
const cacheKey = `${sheetType}-${revision}`
// Если данные уже кэшированы для этой ревизии, возвращаем их
if (cellDataCache.current[cacheKey]) {
return cellDataCache.current[cacheKey]
}
const sheetName = SHEET_NAMES[sheetType]
const cachedData: Record<string, CachedCellData> = {}
// Предварительно получаем все значения для оптимизации
const allCellValues: Record<string, string> = {}
for (let row = 0; row < ROW_COUNT; row++) {
for (let col = 0; col < COL_COUNT; col++) {
const cellKey = `${row}-${col}`
const displayValue = String(
multiSheetEngine.getCellValue(sheetName, row, col) || '',
)
allCellValues[cellKey] = displayValue.trim()
}
}
// Вычисляем hasRightContent для всех ячеек сразу
const rightContentMap: Record<string, boolean> = {}
for (let row = 0; row < ROW_COUNT; row++) {
let hasContentOnRight = false
for (let col = COL_COUNT - 1; col >= 0; col--) {
const cellKey = `${row}-${col}`
rightContentMap[cellKey] = hasContentOnRight
if (allCellValues[cellKey]) {
hasContentOnRight = true
}
}
}
// Формируем кэшированные данные
for (let row = 0; row < ROW_COUNT; row++) {
for (let col = 0; col < COL_COUNT; col++) {
const cellKey = `${row}-${col}`
const rawValue = multiSheetEngine.getCellRawValue(sheetName, row, col)
const displayValue = allCellValues[cellKey]
const cellName = getColumnLabel(col) + (row + 1)
const templateValue = initialTemplateValues.current[cellName] ?? ''
const isModified =
sheetType === 'report' &&
templateValue !== '' &&
rawValue !== templateValue
cachedData[cellKey] = {
displayValue,
rawValue,
isModified,
hasRightContent: rightContentMap[cellKey],
}
}
}
// Очищаем старые кэши для экономии памяти
if (lastRevision.current !== revision) {
Object.keys(cellDataCache.current).forEach((key) => {
if (!key.endsWith(`-${revision}`)) {
delete cellDataCache.current[key]
}
})
lastRevision.current = revision
}
cellDataCache.current[cacheKey] = cachedData
return cachedData
},
[revision, multiSheetEngine, initialTemplateValues],
)
// Синхронизация строки формул // Синхронизация строки формул
const formulaBarValue = useMemo(() => { const formulaBarValue = useMemo(() => {
if (isEditing) { if (isEditing) {
@@ -309,11 +506,11 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
// Фокус на инпуте при начале редактирования // Фокус на инпуте при начале редактирования
useEffect(() => { useEffect(() => {
if (isEditing) { if (isEditing && activeCellInputRef.current) {
if (activeCellInputRef.current) { const input = activeCellInputRef.current
activeCellInputRef.current.focus() input.focus()
activeCellInputRef.current.select() const length = input.value.length
} input.setSelectionRange(length, length)
} }
}, [isEditing]) }, [isEditing])
@@ -341,13 +538,16 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
selectedCell.col, selectedCell.col,
editingValue, editingValue,
) )
// Немедленно обновляем интерфейс для быстрого отклика
updateRevision()
// Запускаем отложенный пересчет для формул
multiSheetEngine.debouncedRecalc() multiSheetEngine.debouncedRecalc()
} }
setIsEditing(false) setIsEditing(false)
setEditingValue('') // Очищаем временное значение setEditingValue('') // Очищаем временное значение
containerRefs.current[activeSheet]?.focus({ preventScroll: true }) containerRefs.current[activeSheet]?.focus({ preventScroll: true })
}, },
[activeSheet, selectedCell, editingValue, multiSheetEngine], [activeSheet, selectedCell, editingValue, multiSheetEngine, updateRevision],
) )
const handleCellChange = useCallback( const handleCellChange = useCallback(
@@ -359,16 +559,25 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
[isEditing], [isEditing],
) )
// Оптимизированная функция очистки ячейки
const handleClearCell = useCallback(() => { const handleClearCell = useCallback(() => {
if (!selectedCell) return if (!selectedCell) return
const sheetName = SHEET_NAMES[activeSheet] const sheetName = SHEET_NAMES[activeSheet]
multiSheetEngine.setCellValue(
// Используем версию без немедленного пересчета для быстрой реакции
multiSheetEngine.setCellValueWithoutRecalc(
sheetName, sheetName,
selectedCell.row, selectedCell.row,
selectedCell.col, selectedCell.col,
'', '',
) )
}, [activeSheet, selectedCell, multiSheetEngine])
// Немедленно обновляем интерфейс для быстрого отклика
updateRevision()
// Запускаем отложенный пересчет
multiSheetEngine.debouncedRecalc()
}, [activeSheet, selectedCell, multiSheetEngine, updateRevision])
const moveSelection = useCallback( const moveSelection = useCallback(
(deltaRow: number, deltaCol: number) => { (deltaRow: number, deltaCol: number) => {
@@ -457,6 +666,11 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
setColumnWidths( setColumnWidths(
produce((draft) => { produce((draft) => {
draft[sheetType][colIndex] = Math.max(60, newWidth) draft[sheetType][colIndex] = Math.max(60, newWidth)
// Принудительно пересчитываем layout грида
const grid = gridRefs.current[sheetType]
if (grid) {
grid.resetAfterColumnIndex(colIndex)
}
}), }),
) )
}, },
@@ -507,10 +721,42 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
[stopEditing, moveSelection, activeSheet], [stopEditing, moveSelection, activeSheet],
) )
const onGridScroll = useCallback(
(
sheetType: SheetType,
{ scrollLeft, scrollTop }: { scrollLeft: number; scrollTop: number },
) => {
if (headerRefs.current[sheetType]) {
headerRefs.current[sheetType]!.scrollLeft = scrollLeft
}
if (rowHeaderRefs.current[sheetType]) {
rowHeaderRefs.current[sheetType]!.scrollTop = scrollTop
}
},
[],
)
// --- Render Functions --- // --- Render Functions ---
const renderSpreadsheet = (sheetType: SheetType) => { const renderSpreadsheet = useCallback(
(sheetType: SheetType) => {
const widths = columnWidths[sheetType] const widths = columnWidths[sheetType]
const sheetName = SHEET_NAMES[sheetType] const cachedData = getCachedCellData(sheetType)
const itemData = {
sheetType,
widths,
selectedCell,
activeSheet,
isEditing,
editingValue,
cachedData,
handleCellClick,
handleCellDoubleClick,
handleCellChange,
stopEditing,
setActiveSheet,
activeCellInputRef,
}
return ( return (
<div <div
@@ -519,6 +765,7 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
tabIndex={0} tabIndex={0}
> >
{/* Header */}
<div className="flex-shrink-0 border-b bg-muted/50 px-3 py-1"> <div className="flex-shrink-0 border-b bg-muted/50 px-3 py-1">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div <div
@@ -531,15 +778,38 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
</h3> </h3>
</div> </div>
</div> </div>
<div className="flex-1 overflow-auto">
<table {/* Spreadsheet Body */}
className="w-full border-collapse" <div className="flex flex-1">
style={{ tableLayout: 'fixed' }} {/* Row Headers */}
<div className="flex-shrink-0 bg-muted">
<div className="flex h-7 w-10 items-center justify-center border-b border-r border-border" />
<div
ref={(el) => (rowHeaderRefs.current[sheetType] = el)}
className="overflow-y-hidden"
style={{ height: 600 }} // This should be dynamic based on container size
> >
<thead> <div>
<tr> {Array.from({ length: ROW_COUNT }).map((_, rowIndex) => (
<th className="h-7 w-10 border border-border bg-muted text-xs font-medium text-muted-foreground"></th> <div
{Array.from({ length: COL_COUNT }, (_, i) => { key={rowIndex}
className="flex h-7 w-10 items-center justify-center border-b border-r border-border text-xs font-medium text-muted-foreground"
>
{rowIndex + 1}
</div>
))}
</div>
</div>
</div>
<div className="flex-1 overflow-hidden">
{/* Column Headers */}
<div
ref={(el) => (headerRefs.current[sheetType] = el)}
className="overflow-x-hidden"
>
<div className="flex">
{Array.from({ length: COL_COUNT }).map((_, i) => {
const handleMouseDown = (e: React.MouseEvent) => { const handleMouseDown = (e: React.MouseEvent) => {
e.preventDefault() e.preventDefault()
const startX = e.clientX const startX = e.clientX
@@ -551,7 +821,10 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
} }
const handleMouseUp = () => { const handleMouseUp = () => {
document.removeEventListener('mousemove', handleMouseMove) document.removeEventListener(
'mousemove',
handleMouseMove,
)
document.removeEventListener('mouseup', handleMouseUp) document.removeEventListener('mouseup', handleMouseUp)
} }
@@ -559,9 +832,9 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
document.addEventListener('mouseup', handleMouseUp) document.addEventListener('mouseup', handleMouseUp)
} }
return ( return (
<th <div
key={i} key={i}
className="relative h-7 border border-border bg-muted text-center text-xs font-medium text-muted-foreground" className="relative flex h-7 flex-shrink-0 items-center justify-center border-b border-r border-border bg-muted text-center text-xs font-medium text-muted-foreground"
style={{ width: widths[i] }} style={{ width: widths[i] }}
> >
{getColumnLabel(i)} {getColumnLabel(i)}
@@ -569,105 +842,58 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({ templateData = {} }) => {
className="absolute right-0 top-0 h-full w-1 cursor-col-resize hover:bg-primary hover:bg-opacity-50" className="absolute right-0 top-0 h-full w-1 cursor-col-resize hover:bg-primary hover:bg-opacity-50"
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
/> />
</th> </div>
) )
})} })}
</tr> </div>
</thead> </div>
<tbody>
{Array.from({ length: ROW_COUNT }).map((_, rowIndex) => (
<tr key={rowIndex}>
<td className="h-7 w-10 border border-border bg-muted text-center text-xs font-medium text-muted-foreground">
{rowIndex + 1}
</td>
{Array.from({ length: COL_COUNT }).map((_, colIndex) => {
const isCellSelected =
selectedCell?.row === rowIndex &&
selectedCell?.col === colIndex &&
activeSheet === sheetType
const isCellEditing = isCellSelected && isEditing
const rawValue = isCellEditing {/* Grid */}
? editingValue <VariableSizeGrid
: multiSheetEngine.getCellRawValue( ref={(el) => (gridRefs.current[sheetType] = el)}
sheetName, columnCount={COL_COUNT}
rowIndex, rowCount={ROW_COUNT}
colIndex, columnWidth={(index: number) => widths[index]}
) rowHeight={() => ROW_HEIGHT}
const displayValue = isCellEditing height={600} // This should be dynamic based on container size
? '' // Не показывать вычисленное значение во время редактирования width={800} // This should be dynamic based on container size
: String( itemData={itemData}
multiSheetEngine.getCellValue( onScroll={(e) => onGridScroll(sheetType, e)}
sheetName, >
rowIndex, {CellRenderer}
colIndex, </VariableSizeGrid>
) || '', </div>
)
const cellName = getColumnLabel(colIndex) + (rowIndex + 1)
const templateValue =
initialTemplateValues.current[cellName] ?? ''
const isModified =
sheetType === 'report' &&
templateValue !== '' &&
rawValue !== templateValue
return (
<Cell
key={colIndex}
sheetType={sheetType}
rowIndex={rowIndex}
colIndex={colIndex}
columnWidth={widths[colIndex]}
isSelected={isCellSelected}
isEditing={isCellEditing}
displayValue={displayValue}
rawValue={rawValue}
isModified={isModified}
onCellClick={handleCellClick}
onCellDoubleClick={handleCellDoubleClick}
onCellValueChange={handleCellChange}
stopEditing={stopEditing}
setActiveSheet={setActiveSheet}
activeCellRef={activeCellInputRef}
/>
)
})}
</tr>
))}
</tbody>
</table>
</div> </div>
</div> </div>
) )
} },
// Используем revision в качестве зависимости, чтобы гарантировать перерисовку
// при изменении данных в движке.
const memoizedReportSheet = useMemo(
() => renderSpreadsheet('report'),
// eslint-disable-next-line react-hooks/exhaustive-deps
[ [
columnWidths.report, columnWidths,
activeSheet, getCachedCellData,
handleKeyDown,
handleColumnResize,
selectedCell, selectedCell,
activeSheet,
isEditing, isEditing,
editingValue, editingValue,
revision, handleCellClick,
handleCellDoubleClick,
handleCellChange,
stopEditing,
setActiveSheet,
onGridScroll,
], ],
) )
// Мемоизированные компоненты листов
const memoizedReportSheet = useMemo(
() => renderSpreadsheet('report'),
[renderSpreadsheet, revision], // Добавляем revision для перерендера
)
const memoizedCalculationsSheet = useMemo( const memoizedCalculationsSheet = useMemo(
() => renderSpreadsheet('calculations'), () => renderSpreadsheet('calculations'),
// eslint-disable-next-line react-hooks/exhaustive-deps [renderSpreadsheet, revision], // Добавляем revision для перерендера
[
columnWidths.calculations,
activeSheet,
selectedCell,
isEditing,
editingValue,
revision,
],
) )
return ( return (

View File

@@ -30,6 +30,28 @@ export function useMultiSheetEngine({
const debouncedRecalcTimeoutRef = useRef<number | null>(null) const debouncedRecalcTimeoutRef = useRef<number | null>(null)
const isRecalculatingRef = useRef(false) const isRecalculatingRef = useRef(false)
// Безопасная функция для вычислений
const safeRecalc = useCallback(() => {
if (!workbookRef.current || isRecalculatingRef.current) return
isRecalculatingRef.current = true
setIsCalculating(true)
try {
workbookRef.current.recalc()
} catch (error) {
console.warn('Ошибка при вычислении:', error)
} finally {
// Уменьшаем задержку для быстрого отклика
setTimeout(() => {
setIsCalculating(false)
isRecalculatingRef.current = false
// Увеличиваем ревизию, чтобы сообщить компонентам о необходимости обновления
setRevision((r) => r + 1)
}, 50) // Уменьшено с 150ms до 50ms
}
}, [])
// Инициализация workbook и листов // Инициализация workbook и листов
useEffect(() => { useEffect(() => {
if (!workbookRef.current) { if (!workbookRef.current) {
@@ -50,8 +72,7 @@ export function useMultiSheetEngine({
setRevision((r) => r + 1) setRevision((r) => r + 1)
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps }, [initialData, safeRecalc, sheets]) // Восстанавливаем зависимости
}, []) // Зависимости убраны, чтобы инициализация проходила один раз
// Синхронизация всех листов из движка // Синхронизация всех листов из движка
const syncAllSheetsFromEngine = useCallback(() => { const syncAllSheetsFromEngine = useCallback(() => {
@@ -89,28 +110,6 @@ export function useMultiSheetEngine({
// setSheetCells(newSheetCells) // Удалено, так как sheetCells убрано // setSheetCells(newSheetCells) // Удалено, так как sheetCells убрано
}, [sheets]) }, [sheets])
// Безопасная функция для вычислений
const safeRecalc = useCallback(() => {
if (!workbookRef.current || isRecalculatingRef.current) return
isRecalculatingRef.current = true
setIsCalculating(true)
try {
workbookRef.current.recalc()
} catch (error) {
console.warn('Ошибка при вычислении:', error)
} finally {
// Небольшая задержка для визуального индикатора
setTimeout(() => {
setIsCalculating(false)
isRecalculatingRef.current = false
// Увеличиваем ревизию, чтобы сообщить компонентам о необходимости обновления
setRevision((r) => r + 1)
}, 150)
}
}, [])
// Отложенный пересчет с дебаунсом // Отложенный пересчет с дебаунсом
const debouncedRecalc = useCallback(() => { const debouncedRecalc = useCallback(() => {
if (!workbookRef.current || isRecalculatingRef.current) return if (!workbookRef.current || isRecalculatingRef.current) return
@@ -120,12 +119,17 @@ export function useMultiSheetEngine({
clearTimeout(debouncedRecalcTimeoutRef.current) clearTimeout(debouncedRecalcTimeoutRef.current)
} }
// Запускаем пересчет через 300ms // Уменьшаем задержку для быстрого отклика
debouncedRecalcTimeoutRef.current = setTimeout(() => { debouncedRecalcTimeoutRef.current = setTimeout(() => {
safeRecalc() safeRecalc()
}, 300) }, 100) // Уменьшено с 300ms до 100ms
}, [safeRecalc]) }, [safeRecalc])
// Функция для немедленного обновления интерфейса без пересчета
const updateRevision = useCallback(() => {
setRevision((r) => r + 1)
}, [])
// Установка значения ячейки без немедленного пересчета // Установка значения ячейки без немедленного пересчета
const setCellValueWithoutRecalc = useCallback( const setCellValueWithoutRecalc = useCallback(
(sheetName: string, row: number, col: number, value: string) => { (sheetName: string, row: number, col: number, value: string) => {
@@ -230,8 +234,6 @@ export function useMultiSheetEngine({
// Пересчет всех формул // Пересчет всех формул
const recalculate = useCallback(() => { const recalculate = useCallback(() => {
if (!workbookRef.current) return
safeRecalc() safeRecalc()
}, [safeRecalc]) }, [safeRecalc])
@@ -250,6 +252,7 @@ export function useMultiSheetEngine({
setCellValue, setCellValue,
setCellValueWithoutRecalc, setCellValueWithoutRecalc,
debouncedRecalc, debouncedRecalc,
updateRevision, // Добавляем новую функцию
getCellValue, getCellValue,
getCellRawValue, getCellRawValue,
getModifiedCells, getModifiedCells,

View File

@@ -1,46 +1,45 @@
ц// Типы элементов интерфейса // Типы элементов интерфейса
export type ElementType = 'text' | 'select' | 'radio' | 'checkbox' | 'number' | 'textarea' | 'date'; export type ElementType =
| 'text'
| 'select'
| 'radio'
| 'checkbox'
| 'number'
| 'textarea'
| 'date'
export interface ElementOption { export interface ElementOption {
value: string; value: string
label: string; label: string
} }
export interface TemplateElement { export interface TemplateElement {
id: string; id: string
type: ElementType; type: ElementType
name: string; name: string
label: string; label: string
targetCell: string; // например "A1", "B5" targetCell: string // например "A1", "B5"
options?: ElementOption[]; // для select и radio options?: ElementOption[] // для select и radio
required?: boolean; required?: boolean
defaultValue?: string; defaultValue?: string
placeholder?: string; placeholder?: string
} }
// Типы шаблонов // Типы шаблонов
export interface Template { export interface Template {
id: string; id: string
name: string; name: string
description?: string; description?: string
excelFile?: File; excelFile?: File
excelData?: Record<string, any>; // данные из Excel excelData?: Record<string, any> // данные из Excel
elements: TemplateElement[]; elements: TemplateElement[]
createdAt: Date; createdAt: Date
updatedAt: Date; updatedAt: Date
} }
// Типы для работы с данными // Типы для работы с данными
export interface TemplateData { export interface TemplateData {
templateId: string; templateId: string
values: Record<string, any>; // elementId -> value values: Record<string, any> // elementId -> value
calculatedCells?: Record<string, any>; // cellName -> value calculatedCells?: Record<string, any> // cellName -> value
}
// Типы для экспорта
export interface ExportData {
templateId: string;
templateName: string;
excelFile: File;
cellUpdates: Record<string, any>; // cellName -> value
} }

252
yarn.lock
View File

@@ -12,6 +12,11 @@
resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
"@babel/runtime@^7.0.0":
version "7.27.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6"
integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==
"@babel/runtime@^7.12.1", "@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2": "@babel/runtime@^7.12.1", "@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2":
version "7.22.5" version "7.22.5"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz"
@@ -19,11 +24,116 @@
dependencies: dependencies:
regenerator-runtime "^0.13.11" regenerator-runtime "^0.13.11"
"@esbuild/android-arm64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd"
integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==
"@esbuild/android-arm@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d"
integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==
"@esbuild/android-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1"
integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==
"@esbuild/darwin-arm64@0.17.19": "@esbuild/darwin-arm64@0.17.19":
version "0.17.19" version "0.17.19"
resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz"
integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==
"@esbuild/darwin-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb"
integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==
"@esbuild/freebsd-arm64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2"
integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==
"@esbuild/freebsd-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4"
integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==
"@esbuild/linux-arm64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb"
integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==
"@esbuild/linux-arm@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a"
integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==
"@esbuild/linux-ia32@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a"
integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==
"@esbuild/linux-loong64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72"
integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==
"@esbuild/linux-mips64el@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289"
integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==
"@esbuild/linux-ppc64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7"
integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==
"@esbuild/linux-riscv64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09"
integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==
"@esbuild/linux-s390x@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829"
integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==
"@esbuild/linux-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4"
integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==
"@esbuild/netbsd-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462"
integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==
"@esbuild/openbsd-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691"
integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==
"@esbuild/sunos-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273"
integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==
"@esbuild/win32-arm64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f"
integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==
"@esbuild/win32-ia32@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03"
integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==
"@esbuild/win32-x64@0.17.19":
version "0.17.19"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061"
integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==
"@eslint-community/eslint-utils@^4.2.0": "@eslint-community/eslint-utils@^4.2.0":
version "4.4.0" version "4.4.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
@@ -121,16 +231,16 @@
resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.15"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/sourcemap-codec@1.4.14": "@jridgewell/sourcemap-codec@1.4.14":
version "1.4.14" version "1.4.14"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.15"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@^0.3.9": "@jridgewell/trace-mapping@^0.3.9":
version "0.3.18" version "0.3.18"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz"
@@ -147,7 +257,7 @@
"@nodelib/fs.stat" "2.0.5" "@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9" run-parallel "^1.1.9"
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5" version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -544,6 +654,51 @@
resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.67.tgz" resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.67.tgz"
integrity sha512-zCT2mCkOBVNf5uJDcQ3A9KDoO1OEaGdfjsRTZTo7sejDd9AXLfJg+xgyCBBrK2jNS/uWcT21IvSv3LqKp4K8pA== integrity sha512-zCT2mCkOBVNf5uJDcQ3A9KDoO1OEaGdfjsRTZTo7sejDd9AXLfJg+xgyCBBrK2jNS/uWcT21IvSv3LqKp4K8pA==
"@swc/core-darwin-x64@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.67.tgz#49da279b06232a388e9c9179db1cbff81d3dee18"
integrity sha512-hXTVsfTatPEec5gFVyjGj3NccKZsYj/OXyHn6XA+l3Q76lZzGm2ISHdku//XNwXu8OmJ0HhS7LPsC4XXwxXQhg==
"@swc/core-linux-arm-gnueabihf@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.67.tgz#668645ac62ea7beb4319d177f43cdefb0326cd90"
integrity sha512-l8AKL0RkDL5FRTeWMmjoz9zvAc37amxC+0rheaNwE+gZya7ObyNjnIYz5FwN+3y+z6JFU7LS2x/5f6iwruv6pg==
"@swc/core-linux-arm64-gnu@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.67.tgz#709bccc5ced37b64ab5ae479bf73fc2ab5ef0b48"
integrity sha512-S8zOB1AXEpb7kmtgMaFNeLAj01VOky4B0RNZ+uJWigdrDiFT67FeZzNHUNmNSOU0QM79G+Lie/xD/beqEw0vDg==
"@swc/core-linux-arm64-musl@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.67.tgz#9187378e17200b1ffb3d06b78c4a33f85dd12efb"
integrity sha512-Fex8J8ASrt13pmOr2xWh41tEeKWwXYGk3sV8L/aGHiYtIJEUi2f+RtMx3jp7LIdOD8pQptor7i5WBlfR9jhp8A==
"@swc/core-linux-x64-gnu@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.67.tgz#bcdaf46c430bc85a59ae9b38ab9bd540aa1fbd2d"
integrity sha512-9bz9/bMphrv5vDg0os/d8ve0QgFpDzJgZgHUaHiGwcmfnlgdOSAaYJLIvWdcGTjZuQeV4L0m+iru357D9TXEzA==
"@swc/core-linux-x64-musl@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.67.tgz#fbb63517cd72eaa3250726a4209c179ada520a57"
integrity sha512-ED0H6oLvQmhgo9zs8usmEA/lcZPGTu7K9og9K871b7HhHX0h/R+Xg2pb5KD7S/GyUHpfuopxjVROm+h6X1jMUA==
"@swc/core-win32-arm64-msvc@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.67.tgz#dadce08f9245c57e9c54c1bbcc815c4bd2077fba"
integrity sha512-J1yFDLgPFeRtA8t5E159OXX+ww1gbkFg70yr4OP7EsOkOD1uMkuTf9yK/woHfsaVJlUYjJHzw7MkUIEgQBucqQ==
"@swc/core-win32-ia32-msvc@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.67.tgz#be026a3a389e64c24fe67a329c04eccf744ac45e"
integrity sha512-bK11/KtasewqHxzkjKUBXRE9MSAidbZCxrgJUd49bItG2N/DHxkwMYu8Xkh5VDHdTYWv/2idYtf/VM9Yi+53qw==
"@swc/core-win32-x64-msvc@1.3.67":
version "1.3.67"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.67.tgz#6fe2f3854d91b58f6e0b00f99366cfd84334b2ea"
integrity sha512-GxzUU3+NA3cPcYxCxtfSQIS2ySD7Z8IZmKTVaWA9GOUQbKLyCE8H5js31u39+0op/1gNgxOgYFDoj2lUyvLCqw==
"@swc/core@^1.3.61": "@swc/core@^1.3.61":
version "1.3.67" version "1.3.67"
resolved "https://registry.npmjs.org/@swc/core/-/core-1.3.67.tgz" resolved "https://registry.npmjs.org/@swc/core/-/core-1.3.67.tgz"
@@ -585,7 +740,7 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-dom@*", "@types/react-dom@^16.8 || ^17.0 || ^18.0", "@types/react-dom@^18.0.11": "@types/react-dom@^18.0.11":
version "18.2.6" version "18.2.6"
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz"
integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A== integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==
@@ -609,7 +764,14 @@
hoist-non-react-statics "^3.3.0" hoist-non-react-statics "^3.3.0"
redux "^4.0.0" redux "^4.0.0"
"@types/react@*", "@types/react@^16.8 || ^17.0 || ^18.0", "@types/react@^18.0.37": "@types/react-window@^1.8.8":
version "1.8.8"
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.8.tgz#c20645414d142364fbe735818e1c1e0a145696e3"
integrity sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.0.37":
version "18.2.14" version "18.2.14"
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz" resolved "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz"
integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g== integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==
@@ -649,7 +811,7 @@
semver "^7.3.7" semver "^7.3.7"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.59.0": "@typescript-eslint/parser@^5.59.0":
version "5.60.1" version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz"
integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q== integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==
@@ -729,7 +891,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: acorn@^8.9.0:
version "8.9.0" version "8.9.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz" resolved "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz"
integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==
@@ -833,7 +995,7 @@ braces@^3.0.2, braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
browserslist@^4.21.5, "browserslist@>= 4.21.0": browserslist@^4.21.5:
version "4.21.9" version "4.21.9"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz"
integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==
@@ -1097,7 +1259,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz"
integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
eslint@*, "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@^8.38.0, eslint@>=7: eslint@^8.38.0:
version "8.44.0" version "8.44.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz" resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz"
integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A== integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==
@@ -1302,18 +1464,6 @@ glob-parent@^6.0.2:
dependencies: dependencies:
is-glob "^4.0.3" is-glob "^4.0.3"
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@7.1.6: glob@7.1.6:
version "7.1.6" version "7.1.6"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
@@ -1326,6 +1476,18 @@ glob@7.1.6:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^13.19.0: globals@^13.19.0:
version "13.20.0" version "13.20.0"
resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz"
@@ -1537,7 +1699,7 @@ lucide-react@^0.525.0:
resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz" resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz"
integrity sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ== integrity sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==
memoize-one@^5.1.1: "memoize-one@>=3.1.1 <6", memoize-one@^5.1.1:
version "5.2.1" version "5.2.1"
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
@@ -1753,7 +1915,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8, postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24, postcss@>=8.0.9: postcss@^8.4.23, postcss@^8.4.24:
version "8.4.24" version "8.4.24"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz"
integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==
@@ -1772,7 +1934,7 @@ prettier-plugin-tailwindcss@^0.4.1:
resolved "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.4.1.tgz" resolved "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.4.1.tgz"
integrity sha512-hwn2EiJmv8M+AW4YDkbjJ6HlZCTzLyz1QlySn9sMuKV/Px0fjwldlB7tol8GzdgqtkdPtzT3iJ4UzdnYXP25Ag== integrity sha512-hwn2EiJmv8M+AW4YDkbjJ6HlZCTzLyz1QlySn9sMuKV/Px0fjwldlB7tol8GzdgqtkdPtzT3iJ4UzdnYXP25Ag==
"prettier@^2.2 || ^3.0", prettier@2.8.8: prettier@2.8.8:
version "2.8.8" version "2.8.8"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
@@ -1782,7 +1944,7 @@ process@^0.11.1:
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
prop-types@^15.7.2, prop-types@^15.8.1, prop-types@15.x: prop-types@15.x, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1" version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -1819,7 +1981,7 @@ react-beautiful-dnd@^13.1.1:
redux "^4.0.4" redux "^4.0.4"
use-memo-one "^1.1.1" use-memo-one "^1.1.1"
"react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom@^16.8.5 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, "react-dom@>= 16.3.0", react-dom@>=16.8, react-dom@>=16.8.0: react-dom@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
@@ -1847,12 +2009,7 @@ react-grid-layout@^1.5.2:
react-resizable "^3.0.5" react-resizable "^3.0.5"
resize-observer-polyfill "^1.5.1" resize-observer-polyfill "^1.5.1"
react-is@^16.13.1: react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^16.7.0:
version "16.13.1" version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -1879,7 +2036,7 @@ react-redux@^7.2.0:
prop-types "^15.7.2" prop-types "^15.7.2"
react-is "^17.0.2" react-is "^17.0.2"
"react-redux@^7.2.1 || ^8.0.2", react-redux@^8.1.1: react-redux@^8.1.1:
version "8.1.1" version "8.1.1"
resolved "https://registry.npmjs.org/react-redux/-/react-redux-8.1.1.tgz" resolved "https://registry.npmjs.org/react-redux/-/react-redux-8.1.1.tgz"
integrity sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA== integrity sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA==
@@ -1941,7 +2098,15 @@ react-style-singleton@^2.2.2, react-style-singleton@^2.2.3:
get-nonce "^1.0.0" get-nonce "^1.0.0"
tslib "^2.0.0" tslib "^2.0.0"
"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react@^16.8.3 || ^17 || ^18", "react@^16.8.5 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18", react@^18.2.0, "react@>= 16.3", "react@>= 16.3.0", react@>=16.8, react@>=16.8.0: react-window@^1.8.11:
version "1.8.11"
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.11.tgz#a857b48fa85bd77042d59cc460964ff2e0648525"
integrity sha512-+SRbUVT2scadgFSWx+R1P754xHPEqvcfSfVX10QYg6POOz+WNgkN48pS+BtZNIMGiL1HYrSEiCkwsMS15QogEQ==
dependencies:
"@babel/runtime" "^7.0.0"
memoize-one ">=3.1.1 <6"
react@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
@@ -1967,7 +2132,7 @@ redux-thunk@^2.4.2:
resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz" resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz"
integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==
redux@^4, "redux@^4 || ^5.0.0-beta.0", redux@^4.0.0, redux@^4.0.4, redux@^4.2.1: redux@^4.0.0, redux@^4.0.4, redux@^4.2.1:
version "4.2.1" version "4.2.1"
resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
@@ -2184,12 +2349,7 @@ tslib@^1.8.1:
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0: tslib@^2.0.0, tslib@^2.1.0:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
tslib@^2.1.0:
version "2.8.1" version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -2213,7 +2373,7 @@ type-fest@^0.20.2:
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
typescript@^5.0.2, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": typescript@^5.0.2:
version "5.1.6" version "5.1.6"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
@@ -2270,7 +2430,7 @@ util@^0.10.3:
dependencies: dependencies:
inherits "2.0.3" inherits "2.0.3"
vite@^4, vite@^4.3.9: vite@^4.3.9:
version "4.3.9" version "4.3.9"
resolved "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz" resolved "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz"
integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg== integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==