UPDATE: Adds bindings to update timezone and locale
UPDATE: Update "generate locale" utility FIX: Minor fixes to UI and proper support for locales/timezones UPDATE: Adds "display language" setting to core
This commit is contained in:
1446
webapp/IronCalc/package-lock.json
generated
1446
webapp/IronCalc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -204,7 +204,9 @@ const MenuDivider = styled("div")`
|
||||
border-top: 1px solid #eeeeee;
|
||||
`;
|
||||
|
||||
const CheckIcon = styled(Check)<{ $active: boolean }>`
|
||||
const CheckIcon = styled(Check, {
|
||||
shouldForwardProp: (prop) => prop !== "$active",
|
||||
})<{ $active: boolean }>`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: ${(props) => (props.$active ? "currentColor" : "transparent")};
|
||||
|
||||
@@ -301,7 +301,9 @@ const TabWrapper = styled("div")<{ $color: string; $selected: boolean }>`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButton = styled(Button)<{ $active: boolean }>`
|
||||
const StyledButton = styled(Button, {
|
||||
shouldForwardProp: (prop) => prop !== "$active",
|
||||
})<{ $active: boolean }>`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 0px;
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { WorkbookState } from "../workbookState";
|
||||
import SheetListMenu from "./SheetListMenu";
|
||||
import SheetTab from "./SheetTab";
|
||||
import type { SheetOptions } from "./types";
|
||||
import { Model } from "@ironcalc/wasm";
|
||||
|
||||
export interface SheetTabBarProps {
|
||||
sheets: SheetOptions[];
|
||||
@@ -22,9 +23,12 @@ export interface SheetTabBarProps {
|
||||
onSheetRenamed: (name: string) => void;
|
||||
onSheetDeleted: () => void;
|
||||
onHideSheet: () => void;
|
||||
onOpenWorkbookSettings: () => void;
|
||||
initialLocale: string;
|
||||
initialTimezone: string;
|
||||
model: Model;
|
||||
onSettingsChange: (
|
||||
locale: string,
|
||||
timezone: string,
|
||||
language: string,
|
||||
) => void;
|
||||
}
|
||||
|
||||
function SheetTabBar(props: SheetTabBarProps) {
|
||||
@@ -105,7 +109,7 @@ function SheetTabBar(props: SheetTabBarProps) {
|
||||
$pressed={false}
|
||||
onClick={() => {
|
||||
setWorkbookSettingsOpen(true);
|
||||
props.onOpenWorkbookSettings();
|
||||
// props.onOpenWorkbookSettings();
|
||||
}}
|
||||
>
|
||||
<EllipsisVertical />
|
||||
@@ -126,8 +130,12 @@ function SheetTabBar(props: SheetTabBarProps) {
|
||||
<WorkbookSettingsDialog
|
||||
open={workbookSettingsOpen}
|
||||
onClose={() => setWorkbookSettingsOpen(false)}
|
||||
initialLocale={props.initialLocale}
|
||||
initialTimezone={props.initialTimezone}
|
||||
initialLocale={props.model.getLocale()}
|
||||
initialTimezone={ props.model.getTimezone()}
|
||||
initialLanguage={props.model.getLanguage()}
|
||||
onSave={(locale: string, timezone: string, language: string) => {
|
||||
props.onSettingsChange(locale, timezone, language);
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
|
||||
@@ -736,6 +736,17 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => {
|
||||
model.hideSheet(selectedSheet);
|
||||
setRedrawId((value) => value + 1);
|
||||
}}
|
||||
onSettingsChange={(
|
||||
locale: string,
|
||||
timezone: string,
|
||||
language: string,
|
||||
) => {
|
||||
model.setLocale(locale);
|
||||
model.setTimezone(timezone);
|
||||
model.setLanguage(language);
|
||||
setRedrawId((id) => id + 1);
|
||||
}}
|
||||
model={model}
|
||||
/>
|
||||
</WorksheetAreaLeft>
|
||||
<RightDrawer
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import styled from "@emotion/styled";
|
||||
import { getAllTimezones, getSupportedLocales } from "@ironcalc/wasm";
|
||||
import {
|
||||
Autocomplete,
|
||||
type AutocompleteProps,
|
||||
Box,
|
||||
Dialog,
|
||||
FormControl,
|
||||
@@ -9,7 +11,7 @@ import {
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import { Check, X } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { theme } from "../../theme";
|
||||
|
||||
@@ -18,49 +20,44 @@ type WorkbookSettingsDialogProps = {
|
||||
onClose: () => void;
|
||||
initialLocale: string;
|
||||
initialTimezone: string;
|
||||
onSave?: (locale: string, timezone: string) => void;
|
||||
initialLanguage: string;
|
||||
onSave: (locale: string, timezone: string, language: string) => void;
|
||||
};
|
||||
|
||||
const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
const { t } = useTranslation();
|
||||
const locales = ["en-US", "en-GB", "de-DE", "fr-FR", "es-ES"];
|
||||
const timezones = [
|
||||
"Berlin, Germany (GMT+1)",
|
||||
"New York, USA (GMT-5)",
|
||||
"Tokyo, Japan (GMT+9)",
|
||||
"London, UK (GMT+0)",
|
||||
"Sydney, Australia (GMT+10)",
|
||||
];
|
||||
const [selectedLocale, setSelectedLocale] = useState<string>(
|
||||
properties.initialLocale && locales.includes(properties.initialLocale)
|
||||
? properties.initialLocale
|
||||
: locales[0],
|
||||
const locales = getSupportedLocales();
|
||||
|
||||
const timezones = getAllTimezones();
|
||||
|
||||
const [selectedLocale, setSelectedLocale] = useState(
|
||||
properties.initialLocale,
|
||||
);
|
||||
const [selectedTimezone, setSelectedTimezone] = useState<string>(
|
||||
properties.initialTimezone && timezones.includes(properties.initialTimezone)
|
||||
? properties.initialTimezone
|
||||
: timezones[0],
|
||||
const [selectedTimezone, setSelectedTimezone] = useState(
|
||||
properties.initialTimezone,
|
||||
);
|
||||
const [selectedLanguage, setSelectedLanguage] = useState(
|
||||
properties.initialLanguage,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (properties.open) {
|
||||
setSelectedLocale(properties.initialLocale);
|
||||
setSelectedTimezone(properties.initialTimezone);
|
||||
setSelectedLanguage(properties.initialLanguage);
|
||||
}
|
||||
}, [
|
||||
properties.open,
|
||||
properties.initialLocale,
|
||||
properties.initialTimezone,
|
||||
properties.initialLanguage,
|
||||
]);
|
||||
|
||||
const handleSave = () => {
|
||||
if (properties.onSave && selectedLocale && selectedTimezone) {
|
||||
properties.onSave(selectedLocale, selectedTimezone);
|
||||
}
|
||||
properties.onSave(selectedLocale, selectedTimezone, selectedLanguage);
|
||||
properties.onClose();
|
||||
};
|
||||
|
||||
// Ensure selectedLocale is always a valid locale
|
||||
const validSelectedLocale =
|
||||
selectedLocale && locales.includes(selectedLocale)
|
||||
? selectedLocale
|
||||
: locales[0];
|
||||
|
||||
// Ensure selectedTimezone is always a valid timezone
|
||||
const validSelectedTimezone =
|
||||
selectedTimezone && timezones.includes(selectedTimezone)
|
||||
? selectedTimezone
|
||||
: timezones[0];
|
||||
|
||||
return (
|
||||
<StyledDialog
|
||||
open={properties.open}
|
||||
@@ -85,10 +82,7 @@ const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
</Cross>
|
||||
</StyledDialogTitle>
|
||||
|
||||
<StyledDialogContent
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
onMouseDown={(event) => event.stopPropagation()}
|
||||
>
|
||||
<StyledDialogContent>
|
||||
<StyledSectionTitle>
|
||||
{t("workbook_settings.locale_and_timezone.title")}
|
||||
</StyledSectionTitle>
|
||||
@@ -99,7 +93,7 @@ const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
<FormControl fullWidth>
|
||||
<StyledSelect
|
||||
id="locale"
|
||||
value={validSelectedLocale}
|
||||
value={selectedLocale}
|
||||
onChange={(event) => {
|
||||
setSelectedLocale(event.target.value as string);
|
||||
}}
|
||||
@@ -113,11 +107,7 @@ const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
}}
|
||||
>
|
||||
{locales.map((locale) => (
|
||||
<StyledMenuItem
|
||||
key={locale}
|
||||
value={locale}
|
||||
$isSelected={locale === selectedLocale}
|
||||
>
|
||||
<StyledMenuItem key={locale} value={locale}>
|
||||
{locale}
|
||||
</StyledMenuItem>
|
||||
))}
|
||||
@@ -149,18 +139,14 @@ const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
<FormControl fullWidth>
|
||||
<StyledAutocomplete
|
||||
id="timezone"
|
||||
value={validSelectedTimezone}
|
||||
value={selectedTimezone}
|
||||
onChange={(_event, newValue) => {
|
||||
setSelectedTimezone((newValue as string) || "");
|
||||
setSelectedTimezone(newValue);
|
||||
}}
|
||||
options={timezones}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
renderOption={(props, option) => (
|
||||
<StyledMenuItem
|
||||
{...props}
|
||||
key={option as string}
|
||||
$isSelected={option === validSelectedTimezone}
|
||||
>
|
||||
<StyledMenuItem {...props} key={option as string}>
|
||||
{option as string}
|
||||
</StyledMenuItem>
|
||||
)}
|
||||
@@ -193,6 +179,49 @@ const WorkbookSettingsDialog = (properties: WorkbookSettingsDialogProps) => {
|
||||
</HelperBox>
|
||||
</FormControl>
|
||||
</FieldWrapper>
|
||||
<FieldWrapper>
|
||||
<StyledLabel htmlFor="display_language">
|
||||
{t("workbook_settings.locale_and_timezone.display_language_label")}
|
||||
</StyledLabel>
|
||||
<FormControl fullWidth>
|
||||
<StyledSelect
|
||||
id="display_language"
|
||||
value={selectedLanguage}
|
||||
onChange={(event) => {
|
||||
setSelectedLanguage(event.target.value as string);
|
||||
}}
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
sx: menuPaperStyles,
|
||||
},
|
||||
TransitionProps: {
|
||||
timeout: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<StyledMenuItem key="en" value="en">
|
||||
{t(
|
||||
"workbook_settings.locale_and_timezone.display_language.english",
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
<StyledMenuItem key="es" value="es">
|
||||
{t(
|
||||
"workbook_settings.locale_and_timezone.display_language.spanish",
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
<StyledMenuItem key="fr" value="fr">
|
||||
{t(
|
||||
"workbook_settings.locale_and_timezone.display_language.french",
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
<StyledMenuItem key="de" value="de">
|
||||
{t(
|
||||
"workbook_settings.locale_and_timezone.display_language.german",
|
||||
)}
|
||||
</StyledMenuItem>
|
||||
</StyledSelect>
|
||||
</FormControl>
|
||||
</FieldWrapper>
|
||||
</StyledDialogContent>
|
||||
|
||||
<DialogFooter>
|
||||
@@ -317,7 +346,15 @@ const RowValue = styled("span")`
|
||||
color: ${theme.palette.grey[500]};
|
||||
`;
|
||||
|
||||
const StyledAutocomplete = styled(Autocomplete)`
|
||||
// Autocomplete with customized styles
|
||||
// Value => string,
|
||||
// multiple => false, (we cannot select multiple timezones)
|
||||
// disableClearable => true, (the timezone must always have a value)
|
||||
// freeSolo => false (the timezone must be from the list)
|
||||
type TimezoneAutocompleteProps = AutocompleteProps<string, false, true, false>;
|
||||
const StyledAutocomplete = styled((props: TimezoneAutocompleteProps) => (
|
||||
<Autocomplete<string, false, true, false> {...props} />
|
||||
))`
|
||||
& .MuiInputBase-root {
|
||||
padding: 0px !important;
|
||||
height: 32px;
|
||||
@@ -369,7 +406,7 @@ const menuPaperStyles = {
|
||||
},
|
||||
};
|
||||
|
||||
const StyledMenuItem = styled(MenuItem)<{ $isSelected?: boolean }>`
|
||||
const StyledMenuItem = styled(MenuItem)`
|
||||
padding: 8px !important;
|
||||
height: 32px !important;
|
||||
min-height: 32px !important;
|
||||
@@ -377,8 +414,15 @@ const StyledMenuItem = styled(MenuItem)<{ $isSelected?: boolean }>`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
background-color: ${({ $isSelected }) =>
|
||||
$isSelected ? theme.palette.grey[50] : "transparent"} !important;
|
||||
|
||||
&.Mui-selected {
|
||||
background-color: ${theme.palette.grey[50]} !important;
|
||||
}
|
||||
|
||||
&.Mui-selected:hover {
|
||||
background-color: ${theme.palette.grey[50]} !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: ${theme.palette.grey[50]} !important;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { expect, test } from "vitest";
|
||||
test("simple calculation", async () => {
|
||||
const buffer = await readFile("node_modules/@ironcalc/wasm/wasm_bg.wasm");
|
||||
initSync(buffer);
|
||||
const model = new Model("workbook", "en", "UTC");
|
||||
const model = new Model("workbook", "en", "UTC", "en");
|
||||
model.setUserInput(0, 1, 1, "=21*2");
|
||||
expect(model.getFormattedCellValue(0, 1, 1)).toBe("42");
|
||||
});
|
||||
|
||||
@@ -181,7 +181,14 @@
|
||||
"locale_example4": "First day of the week",
|
||||
"timezone_label": "Timezone",
|
||||
"timezone_example1": "TODAY()",
|
||||
"timezone_example2": "NOW()"
|
||||
"timezone_example2": "NOW()",
|
||||
"display_language_label": "Display language",
|
||||
"display_language": {
|
||||
"english": "English",
|
||||
"spanish": "Spanish",
|
||||
"french": "French",
|
||||
"german": "German"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const Workbook = () => {
|
||||
useEffect(() => {
|
||||
async function start() {
|
||||
await init();
|
||||
setModel(new Model("Workbook1", "en", "UTC"));
|
||||
setModel(new Model("Workbook1", "en", "UTC", "en"));
|
||||
}
|
||||
start();
|
||||
}, []);
|
||||
|
||||
6
webapp/app.ironcalc.com/frontend/deploy_testing.sh
Executable file
6
webapp/app.ironcalc.com/frontend/deploy_testing.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
set -e
|
||||
rm -rf dist/*
|
||||
npm run build
|
||||
cd dist/assets && brotli wasm* && brotli index-*
|
||||
cd ..
|
||||
scp -r * app.ironcalc.com:~/testing/
|
||||
352
webapp/app.ironcalc.com/frontend/package-lock.json
generated
352
webapp/app.ironcalc.com/frontend/package-lock.json
generated
@@ -91,7 +91,6 @@
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
@@ -571,7 +570,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
|
||||
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
@@ -615,7 +613,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz",
|
||||
"integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
@@ -1154,9 +1151,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/core-downloads-tracker": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.5.tgz",
|
||||
"integrity": "sha512-kOLwlcDPnVz2QMhiBv0OQ8le8hTCqKM9cRXlfVPL91l3RGeOsxrIhNRsUt3Xb8wb+pTVUolW+JXKym93vRKxCw==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.6.tgz",
|
||||
"integrity": "sha512-QaYtTHlr8kDFN5mE1wbvVARRKH7Fdw1ZuOjBJcFdVpfNfRYKF3QLT4rt+WaB6CKJvpqxRsmEo0kpYinhH5GeHg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -1164,16 +1161,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/material": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.5.tgz",
|
||||
"integrity": "sha512-8VVxFmp1GIm9PpmnQoCoYo0UWHoOrdA57tDL62vkpzEgvb/d71Wsbv4FRg7r1Gyx7PuSo0tflH34cdl/NvfHNQ==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.6.tgz",
|
||||
"integrity": "sha512-R4DaYF3dgCQCUAkr4wW1w26GHXcf5rCmBRHVBuuvJvaGLmZdD8EjatP80Nz5JCw0KxORAzwftnHzXVnjR8HnFw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@mui/core-downloads-tracker": "^7.3.5",
|
||||
"@mui/system": "^7.3.5",
|
||||
"@mui/types": "^7.4.8",
|
||||
"@mui/utils": "^7.3.5",
|
||||
"@mui/core-downloads-tracker": "^7.3.6",
|
||||
"@mui/system": "^7.3.6",
|
||||
"@mui/types": "^7.4.9",
|
||||
"@mui/utils": "^7.3.6",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@types/react-transition-group": "^4.4.12",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -1192,7 +1189,7 @@
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.5.0",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@mui/material-pigment-css": "^7.3.5",
|
||||
"@mui/material-pigment-css": "^7.3.6",
|
||||
"@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"
|
||||
@@ -1213,13 +1210,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/private-theming": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.5.tgz",
|
||||
"integrity": "sha512-cTx584W2qrLonwhZLbEN7P5pAUu0nZblg8cLBlTrZQ4sIiw8Fbvg7GvuphQaSHxPxrCpa7FDwJKtXdbl2TSmrA==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.6.tgz",
|
||||
"integrity": "sha512-Ws9wZpqM+FlnbZXaY/7yvyvWQo1+02Tbx50mVdNmzWEi51C51y56KAbaDCYyulOOBL6BJxuaqG8rNNuj7ivVyw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@mui/utils": "^7.3.5",
|
||||
"@mui/utils": "^7.3.6",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1240,9 +1237,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.5.tgz",
|
||||
"integrity": "sha512-zbsZ0uYYPndFCCPp2+V3RLcAN6+fv4C8pdwRx6OS3BwDkRCN8WBehqks7hWyF3vj1kdQLIWrpdv/5Y0jHRxYXQ==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.6.tgz",
|
||||
"integrity": "sha512-+wiYbtvj+zyUkmDB+ysH6zRjuQIJ+CM56w0fEXV+VDNdvOuSywG+/8kpjddvvlfMLsaWdQe5oTuYGBcodmqGzQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4",
|
||||
@@ -1274,16 +1271,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/system": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.5.tgz",
|
||||
"integrity": "sha512-yPaf5+gY3v80HNkJcPi6WT+r9ebeM4eJzrREXPxMt7pNTV/1eahyODO4fbH3Qvd8irNxDFYn5RQ3idHW55rA6g==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.6.tgz",
|
||||
"integrity": "sha512-8fehAazkHNP1imMrdD2m2hbA9sl7Ur6jfuNweh5o4l9YPty4iaZzRXqYvBCWQNwFaSHmMEj2KPbyXGp7Bt73Rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@mui/private-theming": "^7.3.5",
|
||||
"@mui/styled-engine": "^7.3.5",
|
||||
"@mui/types": "^7.4.8",
|
||||
"@mui/utils": "^7.3.5",
|
||||
"@mui/private-theming": "^7.3.6",
|
||||
"@mui/styled-engine": "^7.3.6",
|
||||
"@mui/types": "^7.4.9",
|
||||
"@mui/utils": "^7.3.6",
|
||||
"clsx": "^2.1.1",
|
||||
"csstype": "^3.1.3",
|
||||
"prop-types": "^15.8.1"
|
||||
@@ -1314,9 +1311,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/types": {
|
||||
"version": "7.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.8.tgz",
|
||||
"integrity": "sha512-ZNXLBjkPV6ftLCmmRCafak3XmSn8YV0tKE/ZOhzKys7TZXUiE0mZxlH8zKDo6j6TTUaDnuij68gIG+0Ucm7Xhw==",
|
||||
"version": "7.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.9.tgz",
|
||||
"integrity": "sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4"
|
||||
@@ -1331,13 +1328,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/utils": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.5.tgz",
|
||||
"integrity": "sha512-jisvFsEC3sgjUjcPnR4mYfhzjCDIudttSGSbe1o/IXFNu0kZuR+7vqQI0jg8qtcVZBHWrwTfvAZj9MNMumcq1g==",
|
||||
"version": "7.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.6.tgz",
|
||||
"integrity": "sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@mui/types": "^7.4.8",
|
||||
"@mui/types": "^7.4.9",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"clsx": "^2.1.1",
|
||||
"prop-types": "^15.8.1",
|
||||
@@ -1401,9 +1398,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
|
||||
"integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
|
||||
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1415,9 +1412,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1429,9 +1426,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1443,9 +1440,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
|
||||
"integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1457,9 +1454,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1471,9 +1468,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
|
||||
"integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1485,9 +1482,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
|
||||
"integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1499,9 +1496,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
|
||||
"integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1513,9 +1510,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1527,9 +1524,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1541,9 +1538,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -1555,9 +1552,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -1569,9 +1566,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -1583,9 +1580,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -1597,9 +1594,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -1611,9 +1608,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1625,9 +1622,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1639,9 +1636,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1653,9 +1650,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1667,9 +1664,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -1681,9 +1678,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1695,9 +1692,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2025,13 +2022,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.4.tgz",
|
||||
"integrity": "sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==",
|
||||
"version": "19.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
@@ -2097,9 +2093,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.8.28",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz",
|
||||
"integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==",
|
||||
"version": "2.9.4",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.4.tgz",
|
||||
"integrity": "sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -2107,9 +2103,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.28.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
|
||||
"integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
|
||||
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -2126,13 +2122,12 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.25",
|
||||
"caniuse-lite": "^1.0.30001754",
|
||||
"electron-to-chromium": "^1.5.249",
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
"electron-to-chromium": "^1.5.263",
|
||||
"node-releases": "^2.0.27",
|
||||
"update-browserslist-db": "^1.1.4"
|
||||
"update-browserslist-db": "^1.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
@@ -2164,9 +2159,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001754",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz",
|
||||
"integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==",
|
||||
"version": "1.0.30001759",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz",
|
||||
"integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -2225,9 +2220,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
@@ -2269,9 +2264,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.250",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz",
|
||||
"integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==",
|
||||
"version": "1.5.266",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz",
|
||||
"integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -2696,7 +2691,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -2760,32 +2754,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "19.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
||||
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
||||
"version": "19.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
|
||||
"integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
|
||||
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
|
||||
"version": "19.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz",
|
||||
"integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.2.0"
|
||||
"react": "^19.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "19.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
|
||||
"integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
|
||||
"version": "19.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.1.tgz",
|
||||
"integrity": "sha512-L7BnWgRbMwzMAubQcS7sXdPdNLmKlucPlopgAzx7FtYbksWZgEWiuYM5x9T6UqS2Ne0rsgQTq5kY2SGqpzUkYA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
@@ -2844,9 +2836,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz",
|
||||
"integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
|
||||
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2860,28 +2852,28 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.53.2",
|
||||
"@rollup/rollup-android-arm64": "4.53.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.53.2",
|
||||
"@rollup/rollup-darwin-x64": "4.53.2",
|
||||
"@rollup/rollup-freebsd-arm64": "4.53.2",
|
||||
"@rollup/rollup-freebsd-x64": "4.53.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.2",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.53.2",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.53.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.53.2",
|
||||
"@rollup/rollup-openharmony-arm64": "4.53.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.53.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.53.2",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.53.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.53.2",
|
||||
"@rollup/rollup-android-arm-eabi": "4.53.3",
|
||||
"@rollup/rollup-android-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-x64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-arm64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-x64": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-musl": "4.53.3",
|
||||
"@rollup/rollup-openharmony-arm64": "4.53.3",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.53.3",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -2986,7 +2978,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -2996,9 +2987,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
|
||||
"integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
|
||||
"integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3027,12 +3018,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
|
||||
"integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
|
||||
"version": "7.2.6",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz",
|
||||
"integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -3123,6 +3113,24 @@
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
|
||||
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/eemeli"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ function App() {
|
||||
// Get a remote model
|
||||
try {
|
||||
const model_bytes = await get_model(modelHash);
|
||||
const importedModel = Model.from_bytes(model_bytes);
|
||||
const importedModel = Model.from_bytes(model_bytes, "en");
|
||||
localStorage.removeItem("selected");
|
||||
setModel(importedModel);
|
||||
} catch (_e) {
|
||||
@@ -54,7 +54,7 @@ function App() {
|
||||
} else if (exampleFilename) {
|
||||
try {
|
||||
const model_bytes = await get_documentation_model(exampleFilename);
|
||||
const importedModel = Model.from_bytes(model_bytes);
|
||||
const importedModel = Model.from_bytes(model_bytes, "en");
|
||||
localStorage.removeItem("selected");
|
||||
setModel(importedModel);
|
||||
} catch (_e) {
|
||||
@@ -152,7 +152,7 @@ function App() {
|
||||
const blob = await uploadFile(arrayBuffer, fileName);
|
||||
|
||||
const bytes = new Uint8Array(await blob.arrayBuffer());
|
||||
const newModel = Model.from_bytes(bytes);
|
||||
const newModel = Model.from_bytes(bytes, "en");
|
||||
saveModelToStorage(newModel);
|
||||
|
||||
setModel(newModel);
|
||||
@@ -187,7 +187,7 @@ function App() {
|
||||
}
|
||||
default: {
|
||||
const model_bytes = await get_documentation_model(templateId);
|
||||
const importedModel = Model.from_bytes(model_bytes);
|
||||
const importedModel = Model.from_bytes(model_bytes, "en");
|
||||
saveModelToStorage(importedModel);
|
||||
setModel(importedModel);
|
||||
break;
|
||||
@@ -207,7 +207,7 @@ function App() {
|
||||
onClose={() => setTemplatesDialogOpen(false)}
|
||||
onSelectTemplate={async (fileName) => {
|
||||
const model_bytes = await get_documentation_model(fileName);
|
||||
const importedModel = Model.from_bytes(model_bytes);
|
||||
const importedModel = Model.from_bytes(model_bytes, "en");
|
||||
saveModelToStorage(importedModel);
|
||||
setModel(importedModel);
|
||||
setTemplatesDialogOpen(false);
|
||||
|
||||
@@ -2,10 +2,11 @@ import { Model } from "@ironcalc/workbook";
|
||||
import { base64ToBytes, bytesToBase64 } from "./util";
|
||||
|
||||
const MAX_WORKBOOKS = 50;
|
||||
const DEFAULT_LANGUAGE = "en";
|
||||
|
||||
type ModelsMetadata = Record<
|
||||
string,
|
||||
{ name: string; createdAt: number; pinned?: boolean }
|
||||
{ name: string; createdAt: number; pinned: boolean; language: string }
|
||||
>;
|
||||
|
||||
function randomUUID(): string {
|
||||
@@ -27,11 +28,17 @@ export function updateNameSelectedWorkbook(model: Model, newName: string) {
|
||||
const modelsJson = localStorage.getItem("models");
|
||||
if (modelsJson) {
|
||||
try {
|
||||
const models = JSON.parse(modelsJson);
|
||||
const models: ModelsMetadata = JSON.parse(modelsJson);
|
||||
if (models[uuid]) {
|
||||
models[uuid].name = newName;
|
||||
models[uuid].language = model.getLanguage();
|
||||
} else {
|
||||
models[uuid] = { name: newName, createdAt: Date.now() };
|
||||
models[uuid] = {
|
||||
name: newName,
|
||||
createdAt: Date.now(),
|
||||
language: model.getLanguage(),
|
||||
pinned: false,
|
||||
};
|
||||
}
|
||||
localStorage.setItem("models", JSON.stringify(models));
|
||||
} catch (_e) {
|
||||
@@ -48,26 +55,7 @@ export function getModelsMetadata(): ModelsMetadata {
|
||||
if (!modelsJson) {
|
||||
modelsJson = "{}";
|
||||
}
|
||||
const models = JSON.parse(modelsJson);
|
||||
|
||||
// Migrate old format to new format
|
||||
const migratedModels: ModelsMetadata = {};
|
||||
for (const [uuid, value] of Object.entries(models)) {
|
||||
if (typeof value === "string") {
|
||||
// Old format: just the name string
|
||||
migratedModels[uuid] = { name: value, createdAt: Date.now() };
|
||||
} else if (typeof value === "object" && value !== null && "name" in value) {
|
||||
// New format: object with name and createdAt
|
||||
migratedModels[uuid] = value as { name: string; createdAt: number };
|
||||
}
|
||||
}
|
||||
|
||||
// Save migrated data back to localStorage
|
||||
if (JSON.stringify(models) !== JSON.stringify(migratedModels)) {
|
||||
localStorage.setItem("models", JSON.stringify(migratedModels));
|
||||
}
|
||||
|
||||
return migratedModels;
|
||||
return JSON.parse(modelsJson);
|
||||
}
|
||||
|
||||
// Pick a different name Workbook{N} where N = 1, 2, 3
|
||||
@@ -88,10 +76,10 @@ function getNewName(existingNames: string[]): string {
|
||||
export function createModelWithSafeTimezone(name: string): Model {
|
||||
try {
|
||||
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
return new Model(name, "en", tz);
|
||||
} catch {
|
||||
console.warn("Failed to get timezone, defaulting to UTC");
|
||||
return new Model(name, "en", "UTC");
|
||||
return new Model(name, "en", tz, DEFAULT_LANGUAGE);
|
||||
} catch (e) {
|
||||
console.warn("Failed to get timezone, defaulting to UTC", e);
|
||||
return new Model(name, "en", "UTC", DEFAULT_LANGUAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +92,12 @@ export function createNewModel(): Model {
|
||||
localStorage.setItem("selected", uuid);
|
||||
localStorage.setItem(uuid, bytesToBase64(model.toBytes()));
|
||||
|
||||
models[uuid] = { name, createdAt: Date.now() };
|
||||
models[uuid] = {
|
||||
name,
|
||||
createdAt: Date.now(),
|
||||
language: model.getLanguage(),
|
||||
pinned: false,
|
||||
};
|
||||
localStorage.setItem("models", JSON.stringify(models));
|
||||
return model;
|
||||
}
|
||||
@@ -114,8 +107,9 @@ export function loadSelectedModelFromStorage(): Model | null {
|
||||
if (uuid) {
|
||||
// We try to load the selected model
|
||||
const modelBytesString = localStorage.getItem(uuid);
|
||||
const language = getModelsMetadata()[uuid]?.language || DEFAULT_LANGUAGE;
|
||||
if (modelBytesString) {
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString));
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString), language);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -140,6 +134,14 @@ export function saveSelectedModelInStorage(model: Model) {
|
||||
if (uuid) {
|
||||
const modeBytes = model.toBytes();
|
||||
localStorage.setItem(uuid, bytesToBase64(modeBytes));
|
||||
let modelsJson = localStorage.getItem("models");
|
||||
if (!modelsJson) {
|
||||
modelsJson = "{}";
|
||||
}
|
||||
const models: ModelsMetadata = JSON.parse(modelsJson);
|
||||
models[uuid].language = model.getLanguage(),
|
||||
|
||||
localStorage.setItem("models", JSON.stringify(models));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,16 +153,22 @@ export function saveModelToStorage(model: Model) {
|
||||
if (!modelsJson) {
|
||||
modelsJson = "{}";
|
||||
}
|
||||
const models = JSON.parse(modelsJson);
|
||||
models[uuid] = { name: model.getName(), createdAt: Date.now() };
|
||||
const models: ModelsMetadata = JSON.parse(modelsJson);
|
||||
models[uuid] = {
|
||||
name: model.getName(),
|
||||
createdAt: Date.now(),
|
||||
language: model.getLanguage(),
|
||||
pinned: false,
|
||||
};
|
||||
localStorage.setItem("models", JSON.stringify(models));
|
||||
}
|
||||
|
||||
export function selectModelFromStorage(uuid: string): Model | null {
|
||||
localStorage.setItem("selected", uuid);
|
||||
const modelBytesString = localStorage.getItem(uuid);
|
||||
const language = getModelsMetadata()[uuid]?.language || DEFAULT_LANGUAGE;
|
||||
if (modelBytesString) {
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString));
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString), language);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -210,8 +218,10 @@ export function deleteModelByUuid(uuid: string): Model | null {
|
||||
// If it wasn't the selected model, return the currently selected model
|
||||
if (selectedUuid) {
|
||||
const modelBytesString = localStorage.getItem(selectedUuid);
|
||||
const language =
|
||||
getModelsMetadata()[selectedUuid]?.language || DEFAULT_LANGUAGE;
|
||||
if (modelBytesString) {
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString));
|
||||
return Model.from_bytes(base64ToBytes(modelBytesString), language);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,11 +244,14 @@ export function isWorkbookPinned(uuid: string): boolean {
|
||||
|
||||
export function duplicateModel(uuid: string): Model | null {
|
||||
const originalModel = selectModelFromStorage(uuid);
|
||||
if (!originalModel) return null;
|
||||
if (!originalModel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const duplicatedModel = Model.from_bytes(originalModel.toBytes());
|
||||
const language = originalModel.getLanguage();
|
||||
const duplicatedModel = Model.from_bytes(originalModel.toBytes(), language);
|
||||
const models = getModelsMetadata();
|
||||
const originalName = models[uuid]?.name || "Workbook";
|
||||
const originalName = models[uuid].name;
|
||||
const existingNames = Object.values(models).map((m) => m.name);
|
||||
|
||||
// Find next available number
|
||||
@@ -255,7 +268,12 @@ export function duplicateModel(uuid: string): Model | null {
|
||||
localStorage.setItem("selected", newUuid);
|
||||
localStorage.setItem(newUuid, bytesToBase64(duplicatedModel.toBytes()));
|
||||
|
||||
models[newUuid] = { name: newName, createdAt: Date.now() };
|
||||
models[newUuid] = {
|
||||
name: newName,
|
||||
createdAt: Date.now(),
|
||||
language,
|
||||
pinned: false,
|
||||
};
|
||||
localStorage.setItem("models", JSON.stringify(models));
|
||||
|
||||
return duplicatedModel;
|
||||
|
||||
24
webapp/app.ironcalc.com/server/Cargo.lock
generated
24
webapp/app.ironcalc.com/server/Cargo.lock
generated
@@ -77,6 +77,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
@@ -925,7 +934,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ironcalc"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"bitcode",
|
||||
"chrono",
|
||||
@@ -940,7 +949,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ironcalc_base"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"bitcode",
|
||||
"chrono",
|
||||
@@ -951,6 +960,7 @@ dependencies = [
|
||||
"regex",
|
||||
"ryu",
|
||||
"serde",
|
||||
"statrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1978,6 +1988,16 @@ dependencies = [
|
||||
"loom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "statrs"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
|
||||
@@ -27,8 +27,7 @@ pub async fn add_model(
|
||||
.execute(&mut **db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
io::Error::other(
|
||||
format!("Failed to save to the database: {}", e),
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -36,14 +36,13 @@ async fn download(data: Data<'_>) -> io::Result<FileResponder> {
|
||||
.await
|
||||
.unwrap();
|
||||
if !bytes.is_complete() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
return Err(io::Error::other(
|
||||
"The file was not fully uploaded",
|
||||
));
|
||||
};
|
||||
|
||||
let model = IModel::from_bytes(&bytes).map_err(|e| {
|
||||
io::Error::new(io::ErrorKind::Other, format!("Error creating model, '{e}'"))
|
||||
let model = IModel::from_bytes(&bytes, "en").map_err(|e| {
|
||||
io::Error::other(format!("Error creating model, '{e}'"))
|
||||
})?;
|
||||
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
@@ -51,7 +50,7 @@ async fn download(data: Data<'_>) -> io::Result<FileResponder> {
|
||||
let cursor = Cursor::new(&mut buffer);
|
||||
let mut writer = BufWriter::new(cursor);
|
||||
save_xlsx_to_writer(&model, &mut writer).map_err(|e| {
|
||||
io::Error::new(io::ErrorKind::Other, format!("Error saving model: '{e}'"))
|
||||
io::Error::other(format!("Error saving model: '{e}'"))
|
||||
})?;
|
||||
writer.flush().unwrap();
|
||||
}
|
||||
@@ -82,8 +81,7 @@ async fn share(db: Connection<IronCalcDB>, data: Data<'_>) -> io::Result<String>
|
||||
let hash = id::new_id();
|
||||
let bytes = data.open(MAX_SIZE_MB.megabytes()).into_bytes().await?;
|
||||
if !bytes.is_complete() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
return Err(io::Error::other(
|
||||
"file was not fully uploaded",
|
||||
));
|
||||
}
|
||||
@@ -111,15 +109,14 @@ async fn upload(data: Data<'_>, name: &str) -> io::Result<Vec<u8>> {
|
||||
println!("start upload");
|
||||
let bytes = data.open(MAX_SIZE_MB.megabytes()).into_bytes().await?;
|
||||
if !bytes.is_complete() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
return Err(io::Error::other(
|
||||
"file was not fully uploaded",
|
||||
));
|
||||
}
|
||||
let workbook = load_from_xlsx_bytes(&bytes, name.trim_end_matches(".xlsx"), "en", "UTC")
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Error loading model: '{e}'")))?;
|
||||
let model = IModel::from_workbook(workbook).map_err(|e| {
|
||||
io::Error::new(io::ErrorKind::Other, format!("Error creating model: '{e}'"))
|
||||
.map_err(|e| io::Error::other(format!("Error loading model: '{e}'")))?;
|
||||
let model = IModel::from_workbook(workbook, "en").map_err(|e| {
|
||||
io::Error::other(format!("Error creating model: '{e}'"))
|
||||
})?;
|
||||
println!("end upload");
|
||||
Ok(model.to_bytes())
|
||||
|
||||
Reference in New Issue
Block a user